Question

I have just started to read Professional Test Driven Development with C#: Developing Real World Applications with TDD

I have a hard time understanding stubs, fakes and mocks. From what I understand so far, they are fake objects used for the purpose of unit testing your projects, and that a mock is a stub with conditional logic into it.

Another thing I think I have picked up is that mocks are somehow related with dependency injection, a concept which I only managed to understand yesterday.

What I do not get is why I would actually use them. I cannot seem to find any concrete examples online that explains them properly.

Can anyone please explain to me this concepts?

Était-ce utile?

La solution

As I've read in the past, here's what I believe each term stands for

Stub

Here you are stubbing the result of a method to a known value, just to let the code run without issues. For example, lets say you had the following:

public int CalculateDiskSize(string networkShareName)
{
    // This method does things on a network drive.
}

You don't care what the return value of this method is, it's not relevant. Plus it could cause an exception when executed if the network drive is not available. So you stub the result in order to avoid potential execution issues with the method.

So you end up doing something like:

sut.WhenCalled(() => sut.CalculateDiskSize()).Returns(10);

Fake

With a fake you are returning fake data, or creating a fake instance of an object. A classic example are repository classes. Take this method:

public int CalculateTotalSalary(IList<Employee> employees) { }

Normally the above method would be passed a collection of employees that were read from a database. However in your unit tests you don't want to access a database. So you create a fake employees list:

IList<Employee> fakeEmployees = new List<Employee>();

You can then add items to fakeEmployees and assert the expected results, in this case the total salary.

Mocks

When using mock objects you intend to verify some behaviour, or data, on those mock objects. Example:

You want to verify that a specific method was executed during a test run, here's a generic example using Moq mocking framework:

public void Test()
{
    // Arrange.
    var mock = new Mock<ISomething>();

    mock.Expect(m => m.MethodToCheckIfCalled()).Verifiable();

    var sut = new ThingToTest();

    // Act.
    sut.DoSomething(mock.Object);

    // Assert
    mock.Verify(m => m.MethodToCheckIfCalled());
}

Hopefully the above helps clarify things a bit.

EDIT: Roy Osherove is a well know advocate of Test Driven Development, and he has some very good information on the topic. You may find it very useful :

http://artofunittesting.com/

Autres conseils

They are all variations of the Test Double. Here is a very good reference that explains the differences between them: http://xunitpatterns.com/Test%20Double.html

Also, from Martin Fowler's post: http://martinfowler.com/articles/mocksArentStubs.html

Meszaros uses the term Test Double as the generic term for any kind of pretend object used in place of a real object for testing purposes. The name comes from the notion of a Stunt Double in movies. (One of his aims was to avoid using any name that was already widely used.) Meszaros then defined four particular kinds of double:

  1. Dummy objects: are passed around but never actually used. Usually they are just used to fill parameter lists.
  2. Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
  3. Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.
  4. Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Of these kinds of doubles, only mocks insist upon behavior verification. The other doubles can, and usually do, use state verification. Mocks actually do behave like other doubles during the exercise phase, as they need to make the SUT believe it's talking with its real collaborators.

This PHP Unit's manual helped me a lot as introduction:

"Sometimes it is just plain hard to test the system under test (SUT) because it depends on other components that cannot be used in the test environment. This could be because they aren't available, they will not return the results needed for the test or because executing them would have undesirable side effects. In other cases, our test strategy requires us to have more control or visibility of the internal behavior of the SUT." More: https://phpunit.de/manual/current/en/test-doubles.html

And i find better "introductions" when looking for "test doubles" as mocks, fakes, stubs and the others are known.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top