Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing void methods/mocking object tell-tale signs

When unit testing a codebase, what are the tell-tale signs that I need to utilise mock objects?

Would this be as simple as seeing a lot of calls to other objects in the codebase?

Also, how would I unit test methods which don't return values? So if I a method is returning void but prints to a file, do I just check the file's contents?

Mocking is for external dependencies, so that's literally everything, no? File system, db, network, etc...

like image 207
GurdeepS Avatar asked Feb 12 '10 23:02

GurdeepS


1 Answers

If anything, I probably over use mocks.

Whenever a class makes a call to another, generally I mock that call out, and I verify that the call was made with the correct parameters. Else where, I'll have a unit test that checks the concrete code of the mocked out object behaves correctly.

Example:

[Test]
public void FooMoo_callsBarBaz_whenXisGreaterThan5()
{
    int TEST_DATA = 6;
    var bar = new Mock<Bar>();
    bar.Setup(x => x.Baz(It.Is<int>(i == TEST_DATA)))
       .Verifiable();

    var foo = new Foo(bar.Object);

    foo.moo(TEST_DATA);

    bar.Verify();
}

...
[Test]
public void BarBaz_doesSomething_whenCalled()
{
   // another test
}

The thing for me is, if I try to test lots of classes as one big glob, then there's usually tonnes of setup code. Not only is this quite confusing to read as you try to get your head around all the dependencies, it's very brittle when changes need to be made.

I much prefer small succinct tests. Easier to write, easier to maintain, easier to understand the intent of the test.

like image 134
Kirschstein Avatar answered Oct 23 '22 06:10

Kirschstein