3

I have partial code coverage and I don't know why. for people who like the question before they start reading

Want to start by saying "First Post" as well as I am still very Junior in my development career but I have been a relativly quick learner(imo), so here it goes. Using Nunit to test, and MVP based.

Code to be tested -

void _view_Delete(object sender, EventArgs<Guid> e)
    {
        _agRepo.Delete(_agRepo.GetByID(e.Value));

        var g = _agRepo.GetAll();
        if (g.Count() > 0)
        {
            _view.FillRelatableAccessGroups(g.Where(x => x.IsRelatable));//partial coverage
            _view.FillStandAloneAccessGroups(g.Where(x => !x.IsRelatable));//partial coverage
        }

        else
        {
            _view.ShowErrorMsg(true, "No Access Groups Found.");
        }

    }

The code that is testing the 'if' and the 'else' statements(assuming the repo and view are mocked)-

    [Test]
    public void TestDelete()
    {
        _view.Raise(v => v.Delete += null, this, new EventArgs<Guid>(1.ToGuid()));
        _agRepo.AssertWasCalled(r => r.Delete(_agRepo.GetByID(1.ToGuid())));
        _view.AssertWasCalled(v => v.FillRelatableAccessGroups(Arg<IEnumerable<AccessGroup>>.Is.Anything));
        _view.AssertWasCalled(v => v.FillStandAloneAccessGroups(Arg<IEnumerable<AccessGroup>>.Is.Anything));
    }

    [Test]
    public void TestDeleteNoGroups()
    {
        _agList.Clear();
        _view.Raise(v => v.Delete += null, this, new EventArgs<Guid>(1.ToGuid()));
        _agRepo.AssertWasCalled(r => r.Delete(_agRepo.GetByID(1.ToGuid())));
        _view.AssertWasNotCalled(v => v.FillRelatableAccessGroups(Arg<IEnumerable<AccessGroup>>.Is.Anything));
        _view.AssertWasNotCalled(v => v.FillStandAloneAccessGroups(Arg<IEnumerable<AccessGroup>>.Is.Anything));

        _view.AssertWasCalled(x => x.ShowErrorMsg(true, "No Access Groups Found."));
    }

So my question is, what I am missing in my code. Something more is going on that I need to test and I really would like to find it. I have been heads down in trying to fully understand the in's and out's of testing. Test Driven Development is my goal. If anyone has any kind of input (good or bad) it would be very much appreciated. I wouldn't even mind if someone could throw me juuuuuuuust enough so I can start pulling on that metophorical string that has the answer I am looking for tied to the end of it. I hope I have provided enough information for you all. Thanks!

Eric
  • 699
  • 5
  • 15
  • What part of the code is nunit saying is not being covered by your tests? – Mike Aug 29 '13 at 20:57
  • Its teamcity that states it isn't covered. Nunit tests pass. I have the comments in the code above indicating the code in question. – Eric Aug 29 '13 at 21:12
  • You are asserting that `r.Delete()` was called. That code is not under test. Also, I don't see where you are assigning data to return from `_agRepo.GetAll()`. If you have set it up to return zero items, then `x.IsRelatable` will not be evaluated. Do you have nUnit set up to ignore coverage of simple get/set properties? – Keith Payne Aug 29 '13 at 21:23
  • Hmmm....I think I understand what you're saying. Currently won't be able to test till tomorrow. I am going to see what happens when I set my GetAll to return to something and then assert that the isRelatable is being called when g is accessing the list? Again I do apologize if my vocabulary isn't up to par and feel free to correct me if I use specific words or terms incorrectly. "You dont know what you dont know". Also, not sure how Nunit is configured. It was a standard install and running it as a external debugger. Still new to the team but I can find out if it helps reach the resolution. – Eric Aug 29 '13 at 21:54

2 Answers2

1

_view is mocked and all method's of _view won't operate on it's arguments, e.g. FillRelatableAccessGroups will receive it's argument, but won't use/execute it.

That is why g.Where(x => x.IsRelatable) and g.Where(x => !x.IsRelatable) are not covered by your tests, because they will never be executed.

If you need full test coverage, consider to use a proper implementation of _view. Something like LINQ: Passing lambda expression as parameter to be executed and returned by method

One thing to keep in mind is that there is no TDD doctrine telling you to achieve full test coverage. A covering 90%+ of the most important spots can be much more valuable.

Community
  • 1
  • 1
Jesko R.
  • 827
  • 10
  • 21
  • Wow thank you for the very complete response. Tomorrow I will see what things are covered when I find a means to properly implement the _view and test. I personally know and respect the 90% rule. However I am trying to expand my understanding of unit tests as well as automated testing. What better way of understanding than by doing? I enjoy the practice and breaking, knowing the why's and hows to the issue is the only way to get close to being well versed in the context your studying. Looking forward to the test tomorrow. What are some ways to know what code is worth covering over others? – Eric Aug 29 '13 at 23:03
  • Also just for clarification the _view you're refereeing to is the (I don't know the correct term) 'active' code? Or are you saying the test code? I believe you mean the active code. – Eric Aug 29 '13 at 23:22
  • 1
    Great, keep on breaking the code :). Regarding the question to _view. If you have production code that works in a unit test, feel free to use it. If the production code has an external dependencies that you don't want in a unit test, e.g. using any device, database, file then you have to create a testing variant, or fix the dependency. Hope that makes sense. – Jesko R. Aug 29 '13 at 23:32
  • I have added an answer to my post. I believe I have come to my resolution. I am interested in the business functionality of my answer. Any ideas? – Eric Sep 03 '13 at 17:11
  • 1
    I think I understand what you are trying to say, I am not so sure if it is an easier way forward than using production code. In this case you have to manage your production code as well as those complicated virtual instance methods, which will add up and finally negate the benefit of the mocking framework. However, if it works for you, use and see if really becomes a pain. – Jesko R. Sep 03 '13 at 17:27
  • Well why would you use production code? Doesn't that lead to forced passed tests? So business functionality is going to be based on "how hard/long it is/takes?" Or should it be based on the fact I have code covered? Or does it actually help to continue testing and verifying your code? Just stuck trying to figure out how I would know if it is necessary to even test static Ienumerable methods. Again still new so asking any questions I can. Picking brains...picking brains. – Eric Sep 03 '13 at 17:41
  • 1
    long tests will only occur if your production code has dependencies on stuff that I described as non-unit tests in my response. You can always choose to add an abstraction level to your code, e.g. by using the repository pattern. In the end you won't have the full set of production code, because you always have to inhibit calls to the db, filesystem, etc. but at a certain level it is much easier to mock. – Jesko R. Sep 03 '13 at 17:54
  • Well Jesko thank you very much for your time and knowledge. I feel a lot more comfortable moving forward. I would love to give you some reputation but I am lacking the points. Till next time. =) – Eric Sep 03 '13 at 18:05
1

Disclaimer: I am trying to use terms correctly feel free to corrrect me if I use terms incorrectly please I cannot stress the angst I have for "unlearning" something I soaked up incorrectly. I believe I have found my resolution. The current view does not mock the IEnumerable Where method since it is a static method. I am using RhinoMocks and RhinoMocks library is not strong/large enough to handle those system methods (Correct term?). You can create a virtual instance method in another class to wrap the static method inside thus allowing you to finally have the ability to mock the IEnumerable Where method. I located my answers here at this link: Mocking Static methods using Rhino.Mocks

Community
  • 1
  • 1
Eric
  • 699
  • 5
  • 15