2

I've an inheritance hierarchy which looks like the following:

public class Foo{
        public virtual IList<string> Messages{get;set;}
}

public class Foo2: Foo{
    public bool DoSomething(){
        //Evaluate something;
    }
}

public class Bar: Foo2{
    public override bool DoSomething(){
        var res = base.DoSomething();
        if(res)
            Messages.Add("Hello World");
        return res;
    }
}

My subject under test is Bar and test framework is Moq.

        [TestMethod]
        public void TestBar()
        {

            var mockedBar= new Mock<Bar>() {CallBase = true};
            mockedBar.SetupGet(x => x.Messages).Returns(new List<string>());
            mockedBar.Setup(x => x.DoSomething()).Returns(false);

            var result = mockedBar.Object.DoSomething();

            Assert.IsFalse(result, "This should fail");
            mockedBar.Verify(x => x.DoSomething(), Times.Once, "The base DoSomething is called only once.");
         }

I'm just starting to invest in unit testing and I'm not sure if I'm doing it correctly. Question:

  1. This is passing right now but I'm not confident of my test method. The mockedBar.Setup(x=>x.DoSomething()) should setup my base.DoSomething() call. Is that correct?

  2. How do I test that The Bar.DoSomething() is actually populating the Messages in the Foo class?

Any guidance is much appreciated.

CodeNewa
  • 127
  • 1
  • 7
  • It does not make sense to mock the object you want to test. Usually, you only mock dependencies of the object you want to test. To answer your first question: No, the setup does not setup the base method, but the method of the final object, which is a mock of Bar. – LInsoDeTeh Sep 18 '15 at 14:07
  • I was actually following this [article](http://www.codenutz.com/unit-testing-mocking-base-class-methods-with-moq/). – CodeNewa Sep 18 '15 at 14:21
  • Yes but the author of that article is calling a different method than the one he setups. You're trying to setup the method which you override and which just calls base. – LInsoDeTeh Sep 18 '15 at 14:34

2 Answers2

1

In this case, I don't think you need to mock, just create a Bar object and test normally.

[TestMethod]
public void TestBar()
{
     var bar = new Bar();
     var result = bar.DoSomething();
     Assert.IsFalse(result, "This should fail");
     //I assume that this is your logic.
     Assert.IsTrue(bar.Messages.Contains("Hello World"));
}

We create a mock only when we need to stub or mock external dependencies. In your case, you don't have any external dependencies to mock.

Community
  • 1
  • 1
Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • I'm testing `Bar`. So, wouldn't `Foo` and `Foo2` be the external dependencies? – CodeNewa Sep 18 '15 at 14:14
  • @Ashish Shakya: I don't think so. Inheritance is `is-a` relationship. Not `has-a` relationship (`has an external dependency`). The inherited properties become the part of an object itself, when there is any change in `Foo` or `Foo2` that breaks your code in `Bar`, unit test should detect that. – Khanh TO Sep 18 '15 at 14:15
1

You are setting up a mock and then calling that same mock with this code:

mockedBar.Setup(x => x.DoSomething()).Returns(false);
var result = mockedBar.Object.DoSomething();
Assert.IsFalse(result, "This should fail");

So this doesn't actually call or test your code.

For the example here, I would either not use mocking at all and just test the whole stack or if you can change the code that you are testing, I would look at using dependency injection to remove this inheritance.

Using inheritance to share code makes testing much more difficult.

TomDoesCode
  • 3,580
  • 2
  • 18
  • 34
  • Thanks for confirming my thoughts. I was afraid that I was not testing anything at all. I'll look into the DI workaround as well. Thank you. – CodeNewa Sep 18 '15 at 14:18