NCover results inaccurate when mocking concrete methods

9 posts, 0 answers
  1. Erik
    Erik avatar
    13 posts
    Member since:
    May 2011

    Posted 18 May 2012 Link to this post

    I have a class with multiple public methods in it. Some of these public methods call eachother. In an effort to issolate my tests I mock the calls to other methods in the same concrete class. I mock things up like this:

    Mock.Initialize<PageService>();
    var service = Mock.Create<PageService>();
    Mock.Arrange(() => service.FirstCall()).CallOriginal();
    Mock.Arrange(() => service.SecondCall()).returns(null);
    service.FirstCall();

    Now this works all fine and dandy but it kills my NCover code coverage. Before I changed to mocking the concrete calls I had perfect code coverage. Now the code coverage will show that only the first line of each method is covered. I would like to use JustMock concrete mocking to isolate my tests, but if it kills my metrics then it isn't worth it and I will have to resort to mocking up every object for every call. Is there some setting I am missing?

    On a side note, mocking a concrete call messes up the debugger so that F10 jumps around the method, skipping lines and going to lines it isn't actually hitting. It pretty-much renders debugging it useless.

  2. Erik
    Erik avatar
    13 posts
    Member since:
    May 2011

    Posted 18 May 2012 Link to this post

    I also tried to do partial mocking to accomplish this and that causes my code to fail when the tests are run in a different order. I do this in my first test when I am testing the concrete method.

    Mock.Initialize<PageService>();
    var service = new PageService();
    service.FirstCall()

    I do this in the second method when I want to mock the concrete method:

    Mock.Initialize<PageService>();
    var service = new PageService();
    Mock.Arrange(() => service.FirstCall()).returns(null);
    service.FirstCall();

    But it still calls the original code because the concrete call already happened. Is that really how it is supposed to be? If so then can you never write a test for a call that you want to mock somewhere?
  3. DevCraft R3 2016 release webinar banner
  4. Erik
    Erik avatar
    13 posts
    Member since:
    May 2011

    Posted 18 May 2012 Link to this post

    Ignore my second post. The issue was that initialize was in a base class and was never being called. First post is still a question.
  5. Peter
    Peter avatar
    3 posts
    Member since:
    Sep 2011

    Posted 21 May 2012 Link to this post

    Erik,

    The reason your NCover results are different is because your code is not being run when the mocks are replacing it. If your tests cause other methods to be executed, contributing to your code coverage, then replacing them with a mocked method will remove that method from coverage and lower the overall coverage number.

    Put another way, isolating your tests from each by mocking causes less of your original code to be executed during testing.

    Peter Waldschmidt
    NCover
  6. Erik
    Erik avatar
    13 posts
    Member since:
    May 2011

    Posted 21 May 2012 Link to this post

    Ok, so let me make sure I understand this. Lets say that I have two methods and I write tests for them that fully cover both separately. However, while testing the second method I mock the first then I will lose my coverage on the first. Is that right? Because that is what I see happening.
  7. Peter
    Peter avatar
    3 posts
    Member since:
    Sep 2011

    Posted 21 May 2012 Link to this post

    Yes if I'm understanding you correctly. Mocking a method removes the original method and replaces it with another. So the original method is no longer called...thus you will not see coverage since it is never executed.

    I'm not sure what you mean when you say that your tests "fully cover both separately." If one method calls the other, then they are not really separate, unless I'm misunderstanding you.
  8. Erik
    Erik avatar
    13 posts
    Member since:
    May 2011

    Posted 21 May 2012 Link to this post

    I have two public methods on one class, lets call them A and B. I have tests for A and I have tests for B. B calls A in its tests so I mock A during B's tests. I understand that A won't be covered by B's tests. My issue is that though A is covered by A's tests that is not reflected in NCover. Does that make sense?
  9. Peter
    Peter avatar
    3 posts
    Member since:
    Sep 2011

    Posted 22 May 2012 Link to this post

    OK, that makes sense. I've never seen that before. I'll have to see if I can reproduce this.
  10. Erik
    Erik avatar
    13 posts
    Member since:
    May 2011

    Posted 22 May 2012 Link to this post

    Thanks! Let me know what you find or if you need more details.
Back to Top
DevCraft R3 2016 release webinar banner