Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.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#_Moq - Fatal编程技术网

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

C#和Moq:如何验证一个实例方法是否调用了正确的辅助实例方法?,c#,moq,C#,Moq,我在其他语言(如Ruby)中的模拟方面有很多经验,但我对C#中的Moq是新手,我试图验证对我来说最基本的模拟:验证一个方法是否使用正确的参数调用了正确的方法 我有一个例子主题课 public class Subject { int _age; public Subject(int age) { _age = age; } public void MainMethod() { if(_age <= 13)

我在其他语言(如Ruby)中的模拟方面有很多经验,但我对C#中的Moq是新手,我试图验证对我来说最基本的模拟:验证一个方法是否使用正确的参数调用了正确的方法

我有一个例子主题课

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() {}
}
公共类科目
{
国际年龄;
公共科目(国际年龄)
{
_年龄=年龄;
}
公共方法()
{
如果(_agesubject.KidMethod());
subjectMock.main方法();
}
但很明显我做错了什么,因为我犯了这个错误:

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

我想我对Moq模拟缺乏一些基本的理解,解决这个例子将有助于我理解它

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

更新1 这是在编译:

[Test]
public void MainMethod_ShouldCallKidMethod_IfAgeBelow1()
{
    var subjectMock = new Mock<Subject>(12);
    subjectMock.Object.MainMethod();
    subjectMock.Verify(subject => subject.KidMethod());
}
[测试]
public void main方法\u应调用kid方法\u IfAgeBelow1()
{
var subjectMock=新模拟(12);
subjectMock.Object.main方法();
subjectMock.Verify(subject=>subject.KidMethod());
}
但现在我有一个错误:

System.NotSupportedException:不支持的表达式:subject=>subject.KidMethod() 设置/验证表达式中不能使用不可重写的成员(此处:Subject.KidMethod)

看起来Moq不能与无法重写的方法一起使用1


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

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

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

公共类科目
{
私人只读IHelper\u助手;
国际年龄;
公共主题(IHelper helper,int age)
{
_助手=助手;
_年龄=年龄;
}
公共方法()
{
如果(_ageh.KidMethod());
}

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

如果没有依赖项,则需要测试要测试的类上的一个方法调用要测试的类上的另一个方法

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


参见示例。

Mock
没有给您一个
t
的实例,我认为它有一个名为Object的属性,或者是您想要的类型。另外,我不认为您可以不使用虚拟方法fyiDid您是否尝试过像这样调用方法?
subjectMock.Object.Method1();}
。也请先打这个电话verify@fguillen当单独测试时,被测试的对象通常不会被嘲笑,除非在某些极端的边缘情况下。该示例似乎过于简单,并且稀释了实际问题可能是什么。您需要澄清您实际想要用可用于重现问题的问题,允许更好地理解实际请求的内容。您需要在测试中的
Verify
调用之前移动
main方法的调用。
Verify
方法检查已经发生的方法调用。通常在测试结束时执行。@fguillen这是一个.MOQ不是e此作业的正确工具。调用被测成员后,调用的方法中是否有任何东西可用于验证预期行为?在这样的测试中,观察主体的状态可用于确定行为。这就是为什么我要求查看实际问题的更好表示的代码。是的,我理解,当您正在使用依赖项注入。在我的例子中,我试图验证Subject实例本身中的方法调用,而不是参数对象中的方法调用。我知道模拟概念在这里没有意义,但模拟库(根据我的经验)也用于检查方法调用,而不仅仅是模拟实现。我想我已经理解了,我应该只测试外部更改。我在其他语言中使用了预期的增量单元测试。测试main方法的输出需要很长时间,如果结果不是预期的,我必须进行长时间的调试拥有更详细的内部单元测试在过去帮助我很容易地识别内部步骤错误。但我明白这不是进行单元测试的学术方法。它不是学术性的,因为它是实用的:如果你注意到你必须重新编写大量代码才能正确地测试它,那代码一开始就不好。相反,o如果有一个处理所有事情的大型主方法,则将其拆分为处理特定工作负载的单独单元。
[Test]
public void MainMethod_ShouldCallKidMethod_IfAgeBelow1()
{
    var subjectMock = new Mock<Subject>(12);
    subjectMock.Object.MainMethod();
    subjectMock.Verify(subject => subject.KidMethod());
}