---
title: "Test Driving a Console Application Using String Calculator"
url: "https://courses.osherove.com/courses/the-art-of-unit-testing-and-tdd-master-class-in-net/test-driving-a-console-application-using-string-calculator.md"
canonical: "https://courses.osherove.com/courses/the-art-of-unit-testing-and-tdd-master-class-in-net/test-driving-a-console-application-using-string-calculator/"
tags: []
author: "Roy Osherove"
description: "Lesson 3 of 14 in The Art of Unit Testing & TDD Master Class in .NET (Fakes, Mocks and Stubs), 16:54. Free video by Roy Osherove."
usage: "Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page)."
license: "https://creativecommons.org/licenses/by/4.0/"
---

# Test Driving a Console Application Using String Calculator

1. [Courses](https://courses.osherove.com/#courses)
2. [The Art of Unit Testing & TDD Master Class in .NET](https://courses.osherove.com/courses/the-art-of-unit-testing-and-tdd-master-class-in-net/)
3. Fakes, Mocks and Stubs

Lesson 3 of 14

Duration: 16:54 [Watch on YouTube](https://www.youtube.com/watch?v=wyN6iznigrY)

In this talk, Roy adds a new layer to the application, and uses the existing [string calculator](https://osherove.com/tdd-kata-1 "TDD Kata 1 - String Calculator (osherove.com)"), integrated and used from inside a console application.

It is also the first time the idea of a [mock object](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-4#sigil_toc_id_76 "Interaction testing, mocks, and stubs (The Art of Unit Testing, 3rd ed., ch. 4)") is introduced.

## In this lesson

Roy Osherove test-drives a console application that uses the [string calculator](https://osherove.com/tdd-kata-1 "TDD Kata 1 - String Calculator (osherove.com)") by calling its Main method in memory from a [unit test](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_17 "Defining unit testing, step by step (The Art of Unit Testing, 3rd ed., ch. 1)"), after making Program and Main public. He mentions compiler flags and the [InternalsVisibleTo attribute](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-3#ch03lev1sec6 "Overcoming the encapsulation problem (The Art of Unit Testing, 2nd ed., ch. 3)") for keeping members hidden, then redirects console output with Console.SetOut to a StringWriter over a StringBuilder and checks it with StringAssert. The aim is to connect the string calculator layer to the console layer with a couple of tests, and he moves the console replacement into a [helper method](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-7#ch07lev1sec6 "Building a test API for your application (The Art of Unit Testing, 2nd ed., ch. 7)").

## Transcript

2,224 words

[\[00:26\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=26s) Yesterday we and now we you all have a a very basic version of the [string calculator](https://osherove.com/tdd-kata-1 "TDD Kata 1 - String Calculator (osherove.com)"). What we're going to do now is we're going to try to do to attempt to create a console application that uses the string calculator. Okay. So we're going to try and do it with a [TDD](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_27 "Test-driven development (The Art of Unit Testing, 3rd ed., ch. 1)"). We're going to try to do a test first. But first, I want to explain how how my design cho choices are going to work. So to understand how to test first a console application, let's see what a console application looks like.

[\[01:00\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=60s) So if I go to my solution and I create add new project console application, I'm going to call it string master cuz I want to be able to say string master.exe. What is the structure of the string master? Well, it has a program class. It's not public. It has a main method, which is the main entry point. Let's get rid of this.

[\[01:31\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=91s) And that's not public either. Now, if I want to test drive giving inputs to a console application, instead of creating a new process, etc., I can simply use in-memory calls from my [unit tests](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-1#ch01lev1sec1 "Defining unit testing, step by step (The Art of Unit Testing, 2nd ed., ch. 1)") to actually call this method, the main method. So if I wanted to try and do this, so let's say I would create a new class here and I'd call it usually I'd put this class in a separate project called string master tests or string master unit tests.

[\[02:06\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=126s) In fact, you know what? Let's do that. Add new project class library string master unit tests. You don't have to do it. You can just watch for now because you're going to do the whole thing later anyway. For now, it's important that you just get the concept and the idea of what do I what's optional and what what can I actually change to make things more testable.

[\[02:40\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=160s) I'll just rename this class. And since what I'm going to test is program, the program class, I'm going to say program tests. Also let's set the NuGet package. So, package manager console install package nunit.

[\[03:16\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=196s) Okay, let's create the test fixture. Test fixture. Create a new test. Now in this test, the [unit of work](https://osherove.com/blog/2020/3/12/unit-testing-entry-points-and-exit-points "Unit Testing Entry and Exit Points (osherove.com)") is main cuz that's the main static method cuz that's my entry point. And I'm not going to expect to do anything else but just call the entry point and then check that there was some kind of output to the screen. And we're going to find out how to do that. So main now a basic scenario how do I prove that if I send in some inputs to the main method it actually uses string calculator to write to the screen.

[\[03:53\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=233s) Well remember on the first day I said I don't want to I treat everything between the inputs and the outputs as a black box. So I don't care if it uses string calculator or not. I just care that something was written to the console that is the result. And then I'll just hook up all the internal stuff to make the result happen. So I can say two numbers and

[\[04:24\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=264s) Writes their sum to the console console. Writes is maybe it's not writes but it calls the console with their sum. The reason I'm using the word calls here is because I can't really use the real console. I'm not going to test this visually. So the console is in fact some kind of dependency, something that I cannot control.

[\[04:55\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=295s) So, I'm going to have to somehow replace it or I'm just instead of checking that it the console writes something, I'm just checking that the console was called with the correct parameters because if it was called with correct parameters, I can assume that the UI looks the way I want it to look because I don't have control of the UI. I can just replace it with something else. So I use the word calls to to say that there is that the [end result](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_19 "Exit point types (The Art of Unit Testing, 3rd ed., ch. 1)") is a call to an external system instead of just returns something or throws an exception or changes state.

[\[05:31\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=331s) Now it's a call to an external system that's beyond my control which is a user interface of some sort. Now if I wanted to just call main if I just say program there's no such thing because program is not public. If I go to program I can actually make it public and personally I don't have any program in pro problem in making program public because it's an entry point anyway.

[\[06:03\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=363s) It's not like it has to be hidden. It's a console application. Now if I go here, ReSharper will tell me, hey, do you want to just reference and use program? I'm going to say yes. But now main is not public either. So I'm going to make it public to make it more visible. So I can actually invoke it. Now again, because this is an entry point, it shouldn't be a problem at all. It's an entry point, so anyone should be able to invoke it.

[\[06:33\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=393s) It would just wasn't currently meant for the use of unit test. So I'm just making it usable by unit tests. But in other cases where I make things public, maybe it's more of a security risk. Maybe there's a problem there. And in that case, maybe in terms of design I can choose to make things public because I think it's a better design. Or if I think it's not a good design to make it public, but for [testability](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-11#ch11lev1sec1 "Why should I care about testability in my design? (The Art of Unit Testing, 2nd ed., ch. 11)") I want it to be, I can put it inside

[\[07:04\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=424s) What do you call these? If like debug or if test like this and if so now only during my tests will this thing be public and callable. So I can put things in in compiler flags if I wanted to hide them. Another possibility if I wanted to make things unhidden

[\[07:35\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=455s) Is to not make them public but make them internal. Now internal means that it's public only to the current assembly. But I can also add a special attribute in the in the properties of the project inside assembly info CS and kind of say this assembly [InternalsVisibleTo](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-3#ch03lev1sec6 "Overcoming the encapsulation problem (The Art of Unit Testing, 2nd ed., ch. 3)")

[\[08:11\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=491s) My test assembly whatever the name of the assembly is. And assuming that nothing is strongly named, this should be enough. And then it will look public to a specific assembly because it's been friended. If you have an assembly that has been strongly named, then you're going to have to put the strong the public key. So it looks a bit weird. It's a bit long to generate, but it's still at the end of the day just a string that you put in this attribute.

[\[08:42\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=522s) And and suddenly anything that's internal becomes public to that assembly. So you have ways around this if you still want to keep things hidden. For us right now it doesn't make any any sense not to just make it public. So if I go back to my tests now program main I can now simply in memory invoke this function. So I can say a new string with the value of one and two.

[\[09:17\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=557s) Okay. In fact, I don't even need this. So now I'm able to send an input into my console application in memory and it's fully under my control. But how do I know that something was written or something was calling the console application? If I wanted to replace the console application with something else, actually in the .NET API, we have a built-in way to replace the console.

[\[09:50\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=590s) Now, I'm not sure why this API exists, but probably because someone wanted to test it at the Microsoft headquarters as they wrote the thing. So, they wanted to redirect output to various sources. So what we can do is we can use a special API built in called Console.SetOut. Now Console.SetOut takes a text writer which is an abstract class. So there are multiple things inheriting from text writer. So how do I know which one I I can send?

[\[10:20\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=620s) What are all the things inheriting from test text writer? This is another thing I like in ReSharper is that I can say text writer and then control alt alt h to see the hierarchy of this class or in this case let's see ReSharper inspect oh type hierarchy yeah yep that should have worked oh because I don't have a using that's why alt h now this is the text writer and

[\[10:53\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=653s) What I can also do, let's see, is kind of look at this. Apparently, there's nothing that seems to be inheriting from it. Maybe I'm missing something. Cuz obviously there are things that inherit from it that I'm I'm sure there are. So let's say text writer.

[\[11:28\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=688s) Hm. Interesting. I'm not sure why. Let's see. What if I just say string writer? Well, that that exists. So, I'm not sure why I'm not seeing the type hierarchy right now, but I can tell you that the string writer is an is a version of text writer. Maybe it's a bug or maybe I've just missed something right now. So, I can say string writersw equals a new string writer. Now, string writer writes to a string builder or an in-memory string.

[\[12:00\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=720s) So, I can say just use my string builder here. So I'm going to create a string builder use it inside the string writer and give it the string writer. Now from now on everything that I write to the console if I do this console.Write blah my string builder is going to contain that string.

[\[12:30\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=750s) The console is actually not going to be written at all. the output has been redirected. So I've I've essentially replaced the console output with my own output which is a string builder which I have full control of and it's all in memory. So now I can actually assert at the end of the test that the string builder contains a specific string. I can assert that it also equals a specific string. But that's not usually a good idea because that will make the test more fragile. usually just want to test that a string contains something because a lot of times strings are a form of UI.

[\[13:05\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=785s) So they can contain extra new lines, the dates. We we care about specific things inside the string. So instead of this I'm going to say we call it with main but before that we replace because otherwise if I replace it after the call after the act it's not going to be written to then we can assert and if I wanted to assert on strings there is a a special class I can use built into nunit it's called StringAssert.

[\[13:41\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=821s) It's built into I can say StringAssert and I can use contains or ends with or matches a regular expression. So StringAssert contains three from the string builder to string. Okay, I can also rename it to let's say [fake](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-4#ch04lev1sec2 "The difference between mocks and stubs (The Art of Unit Testing, 2nd ed., ch. 4)") output. Maybe that's a better name.

[\[14:12\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=852s) Okay, so that's an example of how I can take control of a console output and actually use it as a as a test-driven mechanism to to prove that something should be done. Now, currently, if I run this test, it's going to fail. And I want you to get to this stage where that this test actually fails and make it pass as simply as possible. But in this case what we're doing is we're not going to just use say return three because what we want the purpose of this is to connect two layers together.

[\[14:49\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=889s) The purpose is to connect the string calculator layer which we built separately and in testdriven into one layer up which is this layer and we can just have a couple of tests that prove that the layer works. We don't have to write all the test for string calculator again. where what we're testing is that we can shoot one thing into the input and we get back another thing in the output and we assume that everything is actually connected because of that. We we it's okay to have some knowledge about the architecture

[\[15:22\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=922s) But we don't have to care that it calls a specific string calculator class. Okay, questions. Okay, so we're going to split into a pair but it's going to have to be different. So, today you guys can, can pair up and you you'll be working alone today and tomorrow we're going to switch again. Okay.

[\[15:53\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=953s) So by the way, I wanted to add one more thing in terms of refactoring to make this test. I wouldn't do all these three lines in the test. What I would do is after the test would pass is I would refactor something like this. Extract a method call it replace console and I will change the var to use a string builder to make things more readable.

[\[16:23\]](https://www.youtube.com/watch?v=wyN6iznigrY&t=983s) So string builder fake output equals replace console call the program and then make sure that the fake output contains something and then I would use that I it would make the test more readable especially if I'm going to replace this multiple times. So it becomes a utility methods

## Related

- [TDD Kata 2 - Interactions](https://osherove.com/tdd-kata-2) · osherove.com

    The follow-on String Calculator kata that adds interactions, the next step after wiring the calculator into a console app.

- [Overcoming the encapsulation problem](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-3#ch03lev1sec6) · The Art of Unit Testing, 2nd ed., ch. 3

    The 2nd edition's section on the encapsulation problem, covering options like the internal visibility tricks the lesson mentions.

- [Value-based vs. state-based vs. interaction testing](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-4#ch04lev1sec1) · The Art of Unit Testing, 2nd ed., ch. 4

    The 2nd edition's section separating value, state and interaction testing, useful as the lesson starts checking console output.

### Also linked in this lesson

#### The Art of Unit Testing, 3rd ed.

- [Defining unit testing, step by step](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_17), ch. 1
- [Interaction testing, mocks, and stubs](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-4#sigil_toc_id_76), ch. 4
- [Test-driven development](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_27), ch. 1
- [Exit point types](https://livebook.manning.com/book/the-art-of-unit-testing-third-edition/chapter-1#sigil_toc_id_19), ch. 1

#### The Art of Unit Testing, 2nd ed.

- [Building a test API for your application](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-7#ch07lev1sec6), ch. 7
- [Defining unit testing, step by step](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-1#ch01lev1sec1), ch. 1
- [Why should I care about testability in my design?](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-11#ch11lev1sec1), ch. 11
- [The difference between mocks and stubs](https://livebook.manning.com/book/the-art-of-unit-testing-second-edition/chapter-4#ch04lev1sec2), ch. 4

#### osherove.com

- [TDD Kata 1 - String Calculator](https://osherove.com/tdd-kata-1)
- [Unit Testing Entry and Exit Points](https://osherove.com/blog/2020/3/12/unit-testing-entry-points-and-exit-points)

[Previous lesson Test Driving a String Calculator](https://courses.osherove.com/courses/the-art-of-unit-testing-and-tdd-master-class-in-net/test-driving-a-string-calculator/) [Next lesson Introduction to Hand Written Fakes, Mocks and Stubs](https://courses.osherove.com/courses/the-art-of-unit-testing-and-tdd-master-class-in-net/introduction-to-hand-written-fakes-mocks-and-stubs/)


---

## About the author

**Roy Osherove**: Senior Solutions Architect at AWS working on AI for production and AI-driven development; author of The Art of Unit Testing and Elastic Leadership, with about 20 years of consulting and training on unit testing, TDD, team leadership and continuous delivery.

### Sites

- [RobotPaper](https://robotpaper.ai/): This blog: AI patterns and anti-patterns, AI and coding agents, and engineering leadership.
- [osherove.com](https://osherove.com): Roy's personal site. Author of The Art of Unit Testing and Elastic Leadership; consulting and training on unit testing, TDD, team leadership and continuous delivery, plus about 20 years of blog posts.
- [The Art of Unit Testing](https://www.artofunittesting.com): The Art of Unit Testing, 3rd Edition (Manning): readable, maintainable, trustworthy unit tests, plus TDD workshops in C#, JavaScript, Java and Kotlin.
- [5whys.com](https://www.5whys.com): Roy's writing on software team leadership: self-organizing teams, surviving chaos, learning mode and the Elastic Leadership model.
- [Pipeline Driven](https://pipelinedriven.org): Continuous delivery and DevOps practices: build patterns, pipeline-friendly testing, DevOps metrics and enterprise DevOps.
- [Elastic Leadership](https://www.elasticleadership.com): Elastic Leadership, Roy's framework for software team leaders (survival, learning and self-organizing modes).

### Social

- X: https://x.com/royosherove
- LinkedIn: https://www.linkedin.com/in/osherove/

### Contact

- Contact form: https://forms.gle/jQSx5KoXvrVA1JCK7

### License

Licensed under CC BY 4.0 — reuse, quote and adapt with attribution (Roy Osherove, link to the original page). License: https://creativecommons.org/licenses/by/4.0/
