C# Moq运行重写的方法,但未到达方法体的断点

C# Moq运行重写的方法,但未到达方法体的断点,c#,moq,C#,Moq,我模拟了一个类并传递了如下参数: var myClass = new Mock<MyClass>(a.Object, c.Object, b.Object); 我在单元测试中调用Execute方法: myClass.Object.Execute(); 问题是,它似乎执行了该方法,但没有达到我在MyClass中的Execute方法体中所做的断点 当我在没有Moq的情况下实例化MyClass并调用Execute时,它达到了断点 更新 为了得到更多的澄清,我(在提问之前)已经尝试使用C

我模拟了一个类并传递了如下参数:

var myClass = new Mock<MyClass>(a.Object, c.Object, b.Object);
我在单元测试中调用Execute方法:

myClass.Object.Execute();
问题是,它似乎执行了该方法,但没有达到我在
MyClass
中的
Execute
方法体中所做的断点

当我在没有Moq的情况下实例化
MyClass
并调用
Execute
时,它达到了断点

更新

为了得到更多的澄清,我(在提问之前)已经尝试使用
CallBase=true
,但它不起作用。我知道Mock的哲学,我好奇的是,为什么它在不同的名称中不起作用

您可以尝试使用:

myClass.Setup(m => m.Execute(It.IsAny<IDictionary<string, object>>())).CallBase();
myClass.Setup(m=>m.Execute(It.IsAny()).CallBase();
或者在创建模拟实例时,将此CallBase参数传递给它

myClass= new Mock<MyClass>(a.Object, c.Object, b.Object) { CallBase = true };
myClass=newmock(a.Object,c.Object,b.Object){CallBase=true};
有关更多信息,请参见自定义模拟行为部分。 希望它能帮助你

UPD.

下面是我为测试您的案例而编写的代码。我可以说,它击中了myClass中的断点

public abstract class AbstractClass
{
    public abstract void Execute(IDictionary<string, object> parameters);
}

public class A : AbstractClass
{
    public override void Execute(IDictionary<string, object> parameters)
    {
        int i = 0;
    }
}
public class MyClass : A
{
    public override void Execute(IDictionary<string, object> parameters)
    {
        int i = 0;
        Console.WriteLine(i);
    }
}
public class Tests
{
    [Fact]
    public void TestAbstractClass()
    {
        var myClass = new Mock<MyClass>() {CallBase = true};

        myClass.Object.Execute(new Dictionary<string, object>());
    }
}
公共抽象类AbstractClass
{
公共抽象void Execute(IDictionary参数);
}
公共类A:抽象类
{
公共重写无效执行(IDictionary参数)
{
int i=0;
}
}
公共类MyClass:A
{
公共重写无效执行(IDictionary参数)
{
int i=0;
控制台写入线(i);
}
}
公开课考试
{
[事实]
公共无效TestAbstractClass()
{
var myClass=new Mock(){CallBase=true};
myClass.Object.Execute(新字典());
}
}
我很好奇,为什么它在开始时被称为不同的名称时不起作用

这是通过设计
moq


正如我已经说过的,mock为每个mock类型创建代理,注意只能模拟接口、非密封类和抽象\虚拟方法,因为它只是继承基类,然后根据设置行为拦截和处理每个调用。因此,如果您模拟该类,您将获得以下内容:

var myClass = new MyClass(); // it is the instance of MyClass
var myClassMock = new Mock<MyClass>(); // it is the instance of MyClassProxy : MyClass
var myClass=new myClass();//它是MyClass的实例
var myClassMock=new Mock();//它是MyClassProxy的实例:MyClass
这些类型是不同的,如果调用了
myClass.Execute()
,您将清楚地调用IMElementation,但是如果调用
myClassMock.Object.Execute()
,您将最终进入代理类。代理类的默认行为是返回
default(T)
,如果您没有设置任何内容,但可以设置不同的行为,例如:

  • 在您的案例中,通过设置
    CallBase
  • 抛出异常,
    .Setup(…).Throws()
  • 返回非默认值,
    .Setup(…)。返回(值)

问题是,如果您想了解实际行为,为什么要使用mock?模拟背后的哲学是不同的…@Johnny在第一步我想知道为什么它在正常的实例化中工作,为什么它在模拟模式中的行为不同,然后将其更改为你所说的模拟的“哲学”,我已经知道了!Mock为每个被模拟的类型创建代理,请注意,只有接口和虚拟方法才能被模拟,这就是原因,然后根据设置行为拦截和处理每个调用。正如答案所说,如果您想调用实际的方法,那么您应该设置CallBase行为。。。如果你想抛出,你可以设置,如果你想返回非默认值,这也是可能的。使用虚拟方法模拟对象将创建一个新的模拟,该模拟已使用自定义代码覆盖这些方法,默认情况下,它根本不调用原始方法。你说它在“普通实例化”中工作,你是说“与实际对象一起”吗?因为这应该是可行的,这只是正常的行为,你执行代码,它就会到达断点。但是,如果您模拟对象,从而模拟该方法,默认情况下,只有模拟方法才会执行。你说你知道“mock的哲学”,但我不确定你是否完全理解mock是什么。在任何情况下,你都需要发布你的实际代码,你说“myClass.Object.Execute()”,“Object”来自哪里?你能帮我发个帖子吗?我在把问题发到这里之前已经试过了,但没有用。@BabakFakhriloo,我更新了我的答案。过来看。很有效,谢谢。我创建了一个新项目,并测试了您的代码,它工作正常,但我的仍然有问题。我注意到MyClass派生自一个类(称为a),而a派生自抽象类,所以我改变了我的问题。它会影响它的行为吗?@BabakFakhriloo,我已经尝试过你的层次结构,但它仍然可以在MyClass中命中断点。我更新了我的答案。我尝试了你上次的更新,但这次没有成功,在A或MyClass实例中也没有遇到任何断点。如果有任何变化,我会使用Microsoft.VisualStudio.TestTools.UnitTesting。
var myClass = new MyClass(); // it is the instance of MyClass
var myClassMock = new Mock<MyClass>(); // it is the instance of MyClassProxy : MyClass