使用 Moq 确定方法是否被调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/347818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Moq to determine if a method is called
提问by Owen
It is my understanding that I can test that a method call will occur if I call a higher level method, i.e.:
我的理解是,如果我调用更高级别的方法,我可以测试是否会发生方法调用,即:
public abstract class SomeClass()
{
public void SomeMehod()
{
SomeOtherMethod();
}
internal abstract void SomeOtherMethod();
}
I want to test that if I call SomeMethod()
then I expect that SomeOtherMethod()
will be called.
我想测试一下,如果我打电话,SomeMethod()
那么我希望SomeOtherMethod()
会被调用。
Am I right in thinking this sort of test is available in a mocking framework?
我认为这种测试在模拟框架中可用是否正确?
采纳答案by Paul
You can see if a method in something you have mocked has been called by using Verify, e.g.:
您可以使用验证查看您模拟的某个方法是否已被调用,例如:
static void Main(string[] args)
{
Mock<ITest> mock = new Mock<ITest>();
ClassBeingTested testedClass = new ClassBeingTested();
testedClass.WorkMethod(mock.Object);
mock.Verify(m => m.MethodToCheckIfCalled());
}
class ClassBeingTested
{
public void WorkMethod(ITest test)
{
//test.MethodToCheckIfCalled();
}
}
public interface ITest
{
void MethodToCheckIfCalled();
}
If the line is left commented it will throw a MockException when you call Verify. If it is uncommented it will pass.
如果该行被保留注释,则在调用验证时它将抛出 MockException。如果取消注释,它将通过。
回答by Val
No, mock testing assumes you are using certain testable design patterns, one of which is injection. In your case you would be testing SomeClass.SomeMethod
and SomeOtherMethod
must be implemented in another entity which needs to be interfaced.
不,模拟测试假定您正在使用某些可测试的设计模式,其中之一是注入。在您的情况下,您将进行测试SomeClass.SomeMethod
并且SomeOtherMethod
必须在需要连接的另一个实体中实现。
Your Someclass
constructor would look like New(ISomeOtherClass)
. Then you would mock the ISomeOtherClass
and set expectation on its SomeOtherMethod
to be called and verify the expectation.
你的Someclass
构造函数看起来像New(ISomeOtherClass)
. 然后,您将模拟ISomeOtherClass
并设置对其SomeOtherMethod
调用的期望并验证期望。
回答by Johnny
Even though I agree that the @Paul's answeris the recommended way to go I just want to add one alternative way which is provided by moq
off the self.
尽管我同意@Paul 的答案是推荐的方法,但我只想添加一种由moq
自我提供的替代方法。
Since SomeClass
is abstract
it is indeed mockable, but public void SomeMehod()
isn't. The point is to find the way to mock and somehow invoke that method and then using CallBase
propagate the call to the SomeOtherMethod()
. It might sound as a hack but it is simple in essence. It could be used in the case if the proposed refactoring is not possible.
因为SomeClass
是abstract
它确实是mockable,但public void SomeMehod()
并非如此。关键是找到模拟并以某种方式调用该方法的方法,然后使用CallBase
将调用传播到SomeOtherMethod()
. 这可能听起来像黑客,但本质上很简单。如果建议的重构不可能,它可以用于这种情况。
// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
public virtual void DummyMethod() => base.SomeMethod();
}
Then you could setup DummyMethod()
to propagate the call by setting CallBase
flag.
然后你可以设置DummyMethod()
通过设置CallBase
标志来传播调用。
//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();
//Act
mock.Object.SomeMethod();
//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);