Want to use a Mock?

You are wrong! Well in most cases. It seems above the intellectual means of most agile developers (the non-agile developers don’t write tests) to realize that tests like the following are useless and even harmful. It is not giving me anything apart from test sclerosis.

  [Test]
        public void ShouldGetAllByauthorId()
        {
            //given
            var mockRepository = MockRepository.GenerateMock<IContentRepository>();
            var authorRepository = MockRepository.GenerateMock<IAuthorRepository>();
            var subcategoryRepository = MockRepository.GenerateMock<ISubCategoryRepository>();
            var contentService = new ContentService(mockRepository, authorRepository, subcategoryRepository);
 
            //when
            contentService.GetContentByAuthorId(1);
 
            //then
            mockRepository.AssertWasCalled(repository => repository.GetContentByAuthorId(1));
        }

A healthy six lines of code to test this:

   public IList<Voucher> GetContentByAuthorId(long authorId)
        {
            return contentRepository.GetContentByAuthorId(authorId);
        }

Verdict: Waste in an agile disguise.


Posted

in

by

Tags:

Comments

8 responses to “Want to use a Mock?”

  1. Robert Watkins Avatar

    While I fully agree the tests shown above is a waste of time, the real waste of time is the production code being tested.

    Why bother having a class that is wrapping a method in such an inane way? The class itself is useless, so any tests for it will, perforce, be useless as well. This smells like an enforced tiered architecture.

  2. zabil Avatar
    zabil

    you probably don’t need to create all the mocks

    new ContentService(mockRepository, null, null);

    would do?
    It’s enough to test the intent i guess.
    But obviously something wrong when you are writing tests at these level, you do not get an idea of the actual behavior.

  3. msurz Avatar

    +1 with zabil … only 1 mock is needed
    also … u could use an automock container
    also … the way to test a query is to setup a return value not to verify it got called

    [Test]
    public void ShouldGetAllByauthorId()
    {
    var mockRepository = MockRepository.GenerateMock();
    var contentService = new ContentService(mockRepository, authorRepository, subcategoryRepository);

    //given
    var ExpectedVouchers = new List();
    repository.Expect(it => it.GetContentByAuthorId(1)).Return(ExpectedVouchers)

    //when
    var ActualVouchers = contentService.GetContentByAuthorId(1);

    //then
    Assert.AreSame(ExpectedVouchers, ActualVouchers);
    }

  4. Tiest Avatar
    Tiest

    Mocks are for testing side-effects
    Stubs are for getting tests to run

    So I agree with msurz about testing the intent of this code, verifying that something was called (something that should be side-effect free from this code’s point of view) is _bad_.

    But tests like this always perplex me – should we bother with a test at all? And because I don’t know a good answer, I’ll just end up taking the test sclerosis route…

    BTW Felix, do I recognize those avatar images? 😉

  5. Martin Anderson Avatar
    Martin Anderson

    I agree with the others that in this case, only the mock involved needs to be passed in. However in the real world, your ContentServiceTest object would be testing all of its behaviours so you would have some method called before the tests that does all the setup of the object. So you wouldn’t need to worry about the initialisation of the ContentService would be ‘free’ and so reduce your test code to just 2 lines.

    Robert makes a valid point about questioning the validity of such a simple delegate method but sometimes these are required .

    I’m still not sold on the Test Sclerosis issue either. Surely the correct level of coupling (obligatory reference to Law of Demeter inserted here) should ensure that changes to one object should only affect itself and not its parents or grandparents?

    PS And play fair Felix, if you’re going to say that something is bad you can at least put your thinking boots on and suggest a possible solution!

    1. felix Avatar
      felix

      Martin, I lost my thinking boots somewhere near Aldgate, plus the Germans are not exactly known for fair play. So I think even without the two copied lines of useless setup the test is highly questionable. Without further context I’d say there is two possible solutions: a) get rid of the method under test all together (in this case this happened to be the correct solution) b) the delegation was actually legitimate and possibly your test should test the mechanics of that delegation mechanism, i.e. should give us a hint WHY we delegate…

  6. chris Avatar
    chris

    I don’t read what you’re talking about, but putting ones thinking boots on sounds just so great 😀

    Cheers from the engine room.

  7. szczepiq Avatar
    szczepiq

    I hate mocks. Need to find this bastard who gave people mockito. Now they are mocking all the world around them.

    Man, your example is not real, right? There is no sense in such delegating method that does exactly the same? Anyway if your example is real I wouldn’t write a test for it. (Unless it’s a project with junior people, where I simply cannot encourage not writing tests. Even if it means test sclerosis :).

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.