我的理解是,如果我调用更高级别的方法,我可以测试方法调用,即:
public abstract class SomeClass()
{
public void SomeMehod()
{
SomeOtherMethod();
}
internal abstract void SomeOtherMethod();
}
我想测试一下,如果我拨打SomeMethod()
,那么我希望会调用SomeOtherMethod()
。
我是否认为这种测试可以在模拟框架中使用?
答案 0 :(得分:178)
您可以通过使用验证来查看您已模拟的某个方法是否被调用,例如:
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();
}
如果对该行进行了注释,则在调用Verify时将抛出MockException。如果它被取消注释,它将通过。
答案 1 :(得分:6)
不,模拟测试假设您正在使用某些可测试的设计模式,其中一个是注入。在您的情况下,您将测试SomeClass.SomeMethod
并且SomeOtherMethod
必须在需要接口的另一个实体中实现。
您的Someclass
构造函数看起来像New(ISomeOtherClass)
。然后你会模拟ISomeOtherClass
并设置其SomeOtherMethod
的期望值并验证期望值。
答案 2 :(得分:-1)
即使我同意@Paul's answer是推荐的使用方式,但我只想添加moq
自身提供的另一种方式。
由于SomeClass
是abstract
,因此它确实是可模拟的,但public void SomeMehod()
却不是。关键是找到模拟方法并以某种方式调用该方法,然后使用CallBase
将调用传播到SomeOtherMethod()
。听起来可能很hack,但本质上很简单。如果无法进行建议的重构,则可以使用它。
// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
public virtual void DummyMethod() => base.SomeMethod();
}
然后,您可以设置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);