C# 和 Moq:如何验证实例方法是否调用了正确的辅助实例方法? 更新 1

如何解决C# 和 Moq:如何验证实例方法是否调用了正确的辅助实例方法? 更新 1

我在使用 Ruby 等其他语言进行 Mocking 方面有很多经验,但我是 C# 中的 Moq 的新手,我正在尝试验证对我来说最基本的 Mock:验证方法是否正在调用正确的方法使用适当的参数。

我有这个示例主题

public class Subject
{
    int _age;

    public Subject(int age)
    {
        _age = age;
    }

    public void MainMethod()
    {
        if(_age <= 13)
        {
            KidMethod();
        }
        else
        {
            AdultMethod();
        }
    }

    public void KidMethod() {}
    public void AdultMethod() {}
}

我正在尝试创建此测试:

[Test]
public void MainMethod_ShouldCallKidMethod_IfAgeBelow1()
{
    var subjectMock = new Mock<Subject>(12);
    subjectMock.Verify(subject => subject.KidMethod());
    subjectMock.MainMethod();
}

但显然我做错了什么,因为我收到了这个错误

错误 CS1061:“Mock”不包含“MainMethod”的定义,并且找不到接受“Mock”类型的第一个参数的可访问扩展方法“MainMethod”(您是否缺少 using 指令或程序集引用? )

我想我缺少对 Mocking with Moq 的一些基本理解,解决这个例子将帮助我得到它。

我一直在检查 SO 中的类似问题,但我检查过的所有问题都涵盖了更具体的案例,我没有发现有人解决了这个简单的一般案例。

更新 1

这是编译:

[Test]
public void MainMethod_ShouldCallKidMethod_IfAgeBelow1()
{
    var subjectMock = new Mock<Subject>(12);
    subjectMock.Object.MainMethod();
    subjectMock.Verify(subject => subject.KidMethod());
}

但现在我有错误

System.NotSupportedException:不支持的表达式:subject => subject.KidMethod() 不可覆盖的成员(此处:Subject.KidMethod)不得用于设置/验证表达式。

看起来 Moq 不能与不能被覆盖的方法一起使用 1

没有办法做我正在尝试的事情吗?

解决方法

关键是你要求的不是你应该做的。是的,模拟框架可以验证方法调用,在模拟上。您模拟依赖项。

您没有依赖项,您想测试要测试的类上的方法是否调用了要测试的类上的另一个方法。

这不是嘲笑或单元测试的目的,你在这里做错了。在同一个类上调用另一个方法的方法是一个实现细节,而不是你应该测试的东西。重要的是方法的输出,或者方法调用后对象的状态。测试那个

参见示例 How to use Moq in unit test that calls another method in same class

,

你的例子对我来说没有多大意义:你试图模拟你正在测试的同一个类的某些方法。这是一个更典型的例子。

你的类可能会使用一些接口:

public class Subject
{
    private readonly IHelper _helper;
    int _age;

    public Subject(IHelper helper,int age)
    {
        _helper = helper;
        _age = age;
    }

    public void MainMethod()
    {
        if(_age <= 13)
        {
            _helper.KidMethod();
        }
        else
        {
            _helper.AdultMethod();
        }
    }
}

因此您的测试将模拟该界面。这样,我们只是在孤立地测试 Subject

[Test]
public void MainMethod_ShouldCallKidMethod_IfAgeBelow1()
{
    // Arrange.
    var helperMock = new Mock<IHelper>();
    var subject = new Subject(helperMock.Object,12);

    // Act.
    subject.MainMethod();

    // Assert.
    helperMock.Verify(h => h.KidMethod());
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?