简体   繁体   English

使用Moq调用验证受保护的抽象方法

[英]Verifying protected abstract methods are called using Moq

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. 我正在使用Moq,我想编写一个测试来验证当我调用BaseMethod()并且runMethod1为true时调用ChildMethod1()。 Is it possible to create an implemention of TestBase with Moq, call BaseMethod() and verify that ChildMethod was called on the Moq implementation? 是否可以使用Moq创建TestBase的实现,调用BaseMethod()并验证是否在Moq实现上调用了ChildMethod?

[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

}

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. 编辑此语法在当前版本的Moq中不起作用。 See this question for how to do it as of at least 4.0.10827 请参阅此问题 ,了解如何执行此操作至少4.0.10827

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. 您可以使用Moq模拟受保护的方法,并通过严格模拟,您可以验证它们是否被调用。 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();
}

这有点像黑客,但如何创建一个使ChildMethod1和ChildMethod公开然后Moqing的TestBase的子类呢?

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?" “是否可以使用Moq创建TestBase的实现,调用BaseMethod()并验证是否在Moq实现上调用了ChildMethod?”

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? descendatn类是否返回与基类不同的值? If so you can test for that and ignore implimentation details (makes refactoring alot easier too). 如果是这样,你可以测试它并忽略implimentation细节(使重构也更容易)。

  2. Does the descendant class call different methods or different dependencies? 后代类是否调用不同的方法或不同的依赖项? If so you can check the dependencies. 如果是这样,您可以检查依赖项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM