Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Moq确定是否调用了方法_C#_.net_Unit Testing_Mocking_Moq - Fatal编程技术网

C# 使用Moq确定是否调用了方法

C# 使用Moq确定是否调用了方法,c#,.net,unit-testing,mocking,moq,C#,.net,Unit Testing,Mocking,Moq,我的理解是,如果我调用更高级别的方法,我可以测试是否会发生方法调用,即: public abstract class SomeClass() { public void SomeMehod() { SomeOtherMethod(); } internal abstract void SomeOtherMethod(); } 我想测试一下,如果我调用SomeMethod(),那么我希望调用SomeOtherMethod() 我认为这种测

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

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

    internal abstract void SomeOtherMethod();
}
我想测试一下,如果我调用
SomeMethod()
,那么我希望调用
SomeOtherMethod()


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

您可以通过使用Verify查看您模拟的对象中的方法是否已被调用,例如:

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();
}
static void Main(字符串[]args)
{
Mock Mock=新Mock();
ClassBeingTested testedClass=新ClassBeingTested();
testedClass.WorkMethod(mock.Object);
mock.Verify(m=>m.MethodToCheckIfCalled());
}
正在测试的类
{
公共空隙法(ITest试验)
{
//test.MethodToCheckIfCalled();
}
}
公共接口测试
{
void MethodToCheckIfCalled();
}

如果该行保留注释,则在调用Verify时将抛出MockException。如果没有注释,它将通过。

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


您的
Someclass
构造函数看起来像
New(isomootherclass)
。然后模拟
isomootherclass
,设置调用它的
SomeOtherMethod
的期望值,并验证期望值

尽管我同意这是推荐的方法,但我只想添加一种由
moq
提供的替代方法

因为
SomeClass
abstract
它确实是可以模仿的,但是
public void somehod()
不是。关键是找到模拟并以某种方式调用该方法的方法,然后使用
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();
}
然后您可以设置
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);
//排列
var mock=new mock();
mock.Setup(m=>m.DummyMethod()).CallBase();
//表演
mock.Object.SomeMethod();
//断言
mock.Verify(m=>m.SomeOtherMethod(),Times.Once);

这是正确答案。然而,你必须明白一些事情。不能模拟非抽象或虚拟的方法/属性(显然,所有接口方法和属性都可以模拟)。-1:Expect(…).Verifiable()在此代码中是多余的。使用AAA验证您所拥有的是正确的。可验证的用于.Verify()即.e。无参数版本。请看@I——是的,它可以投票表决,因为它更复杂,需要一个样板文件DummyClassUpPosited,因为有时您无法重构,您需要按原样测试实现