views:

1218

answers:

5

Suppose I have the following class:

public class TestBase
{
  public bool runMethod1 { get; set; }

  public void BaseMethod() 
  {
    if (runMethod1)
      ChildMethod1();
    else 
      ChildMethod2();
  }

  protected abstract void ChildMethod1();
  protected abstract void ChildMethod2();
}

I also have the class

public class ChildTest : TestBase
{
  protected override void ChildMethod1()
  {
    //do something
  } 

  protected override void ChildMethod2()
  {
    //do something completely different
  }

}

I'm using Moq, and I'd like to write a test that verifies ChildMethod1() is being called when I call BaseMethod() and runMethod1 is true. Is it possible to create an implemention of TestBase with Moq, call BaseMethod() and verify that ChildMethod was called on the Moq implementation?

[Test]
public BaseMethod_should_call_correct_child_method()
{
  TestBase testBase;

  //todo: get a mock of TestBase into testBase variable

  testBase.runMethod1 = true;

  testBase.BaseMethod();

  //todo: verify that ChildMethod1() was called

}
A: 

It seems like your testing the behaviour rather than the public interface. If this is intended then you could probably look at advice for testing private members.

"Is it possible to create an implemention of TestBase with Moq, call BaseMethod() and verify that ChildMethod was called on the Moq implementation?"

It's sort of possible. But then you would be testing the mock object, not the real object.

Two questions that might steer you in the right direction:

  1. Does the descendatn class return a different value than the base class? If so you can test for that and ignore implimentation details (makes refactoring alot easier too).

  2. Does the descendant class call different methods or different dependencies? If so you can check the dependencies.

flukus
A: 

It's a bit of a hack, but how about creating a subclass of TestBase that makes ChildMethod1 and ChildMethod public and then Moqing that?

David Norman
+3  A: 

I figured out how to do this. You can can mock protected methods with Moq, and by making a strict mock, you can verify that they were called. Now I can test the base class without having to make any subclasses.

[Test]
public BaseMethod_should_call_correct_child_method()
{
  //strict mocks will make sure all expectations are met
  var testBaseMock = new Mock<TestBase>(MockBehavior.Strict);

  //expect that ChildMethod1() will be called once. (it's protected)
  testBaseMock.Protected().Expect("ChildMethod1")
    .AtMostOnce();

  var testBase = testBaseMock.Object;

  testBase.runMethod1 = true;
  testBase.BaseMethod();

  //make sure the method was called
  testBase.VerifyAll();
}
Lance Fisher
Nice - helped me out
orip
+3  A: 

Added this as an enhancement oportunity to Moq.

Thanks!

kzu
good to see you on SO :)
orip
Nice! Thanks for the comment. I'm a fan of Moq, and your blog.
Lance Fisher
+3  A: 

You can also set the expectation/setup as Verifiable and do without a strict mock:

  //expect that ChildMethod1() will be called once. (it's protected)
  testBaseMock.Protected().Expect("ChildMethod1")
    .AtMostOnce()
    .Verifiable();

  ...

  //make sure the method was called
  testBase.Verify();

Edit This syntax does not work in current versions of Moq. See this question for how to do it as of at least 4.0.10827

kzu