162

据我了解,如果我调用更高级别的方法,我可以测试是否会发生方法调用,即:

public abstract class SomeClass()
{    
    public void SomeMehod()
    {
        SomeOtherMethod();
    }

    internal abstract void SomeOtherMethod();
}

我想测试一下,如果我打电话,SomeMethod()那么我希望SomeOtherMethod()会被调用。

我认为这种测试在模拟框架中可用吗?

4

3 回答 3

187

您可以通过使用验证来查看您已模拟的某个方法是否已被调用,例如:

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();
}

如果该行被留下注释,它会在你调用验证时抛出一个 MockException。如果未注释,它将通过。

于 2008-12-07T18:49:13.060 回答
6

不,模拟测试假定您正在使用某些可测试的设计模式,其中之一是注入。在您的情况下,您将进行测试SomeClass.SomeMethod ,并且SomeOtherMethod必须在另一个需要接口的实体中实现。

您的Someclass构造函数看起来像New(ISomeOtherClass). 然后,您将模拟并对其调用ISomeOtherClass设置期望并验证期望。SomeOtherMethod

于 2011-02-23T22:35:56.737 回答
0

尽管我同意@Paul 的回答是推荐的方式,但我只想添加一种由moq自我提供的替代方式。

因为SomeClassabstract确实是可模拟的,但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);
于 2019-04-17T07:26:06.117 回答