Since our school years we have been conducted to tests. Class tests, which provided if pupil knows given subject, medical tests proving status about our health, or even surveys providing knowledge for research purposes. Named things were destined for one thing – to give information about something and in the result, to draw exact conclusions.
Programming provides tests as well. Today there are many principles of writing clean code and methods of testing, which should lead programmers. Test Driven Development is an approach of software creating and testing – this approach assumes, that before writing appropriate functionality, developer should write a test, which very often at the beginning fails everything – after failure, developer writes correctly code with proper functionalities.

Picture above displays three steps in TDD technique.
Failing Step – Firstly, test is written – it cannot be passed, because of functionality which can’t be implemented. It is possible, that even after writing such a test, the code won’t work. IDE displays test as red coloured.
Second Step – relies on writing test which implements missing in first step functionality. This case establishes writing code which is not perfectly clean – it is about quickly writing missing functionality. After that, we confirm that our implementation is good enough by launching tests. If everything is correct, IDE should light on green colour.
Refactor – last step of TDD technique. This step has to clean up redundant mess created before, but not changing written functionality. Giving an example – creating a method which deletes duplicated code, or even creating another class responsible for partially other class.
public class UnitTest
{
[Fact]
public void addingToValuesToDatabase()
{
//arrange
Database database= new Database();
}
}
Created code above doesn’t pass test because of of missing Database class – first step of test failing is check.
Let’s create Database class:
public class Database { }
This time, code passes test correctly – we’ve made 2nd step. 3rd step is to refactor our code, however we don’t have to refactor anything in our code, then one cycle of test development is made correctly. Now we add new lines of code:
public class UnitTest
{
[Fact]
void addingToValuesToDatabase()
{
//arrange
Database database = new Database();
Value value= new Value(1, "Contact");
//act
database.add(value);
}
}
This time, code doesn’t pass the test, due to missing add method in Database class. Now it’s time to create add method to class:
public class Database{
public void add(Value value){ }
}
In this moment, code should pass the test. Refactor is not yet required – 2nd cycle of tests has been made. What is worth to pay attention, is every step is iterating like in standard loop – we add only some parts of code, which are crucial to pass the test, no more. Next steps are made similar – adding some code, checking if test fails, then creating the code to pass the test, and at the end its only a matter of refactor, to keep code clean.
Three musketeers of Unit Tests
Stub
Stubs are examples of code implementation, which behaviour we are willing to test – here we give an example implementation of interface, in which we pass some example data. They are perfect for simple methods, unfortunately not for complex interfaces.
[Fact]
public void ValidateAgeExample()
{
var ageValidate= new AgeValidator();
var ageMock= new Mock<IAge>();
ageMock.Setup(c => c.GetAge()).Returns(21);
var age= ageMock.Object;
bool validate = ageValidator.Validate(age);
validate.Should().BeTrue();
}
Mock
Mock is able to verify behaviour of tested object, so it’s purpose is to check if given component is performed. Mocks are object, which simulate real behaviours of real objects and code. They are made during program’s work, and are more flexible than stub’s.
[Fact]
public void ValidateAgeExample()
{
var ageValidator= new AgeValidator();
var ageMock= new Mock<IAge>();
ageMock.Setup(c => c.GetAge()).Returns(21);
var age= ageMock.Object;
ageValidator.Validate(age);
ageMock.Verify(x => x.GetAge(), Times.Once);
}
Spy
In simple terms – its a mock with additional functionality, but spy checks quantity of calls. Its an wrapping object, which wraps an object of given class and in the end it tracks and verifies mocking objects and methods. Object spy is partially a mock, and partially a normal object
[Fact]
public void ValidateAgeExample()
{
var ageValidator= new AgeValidator();
var ageSpy= new Mock<IAge>();
var age= ageSpy.Object;
ageValidator.Validate(age);
ageSpy.Verify(x => x.GetAge(), Times.Once);
}
To sum up, TDD is very crucial programming’s element – it allows developers in easier and faster way find bugs in code, tests are flexible and the results are instant. but it has disadvantages as well – longer time of development, or time consuming for development preparation.