C# Moq-检查方法是否模拟(设置为模拟)

C# Moq-检查方法是否模拟(设置为模拟),c#,.net,unit-testing,moq,C#,.net,Unit Testing,Moq,我们都知道,在Moq中,我们可以使用Setup模拟该方法。如何检查是否正在设置该方法?我不想调用该方法并检查其结果,因为在Verify期间,这将作为对模拟方法的实际调用计算(除非您可以告诉我如何使其不计算-这也将作为一个答案计算)。实际上,我刚刚找到了Mock上定义的ResetCalls方法,这将重置计数器。这可能会对我有所帮助,因为我可以调用父方法并将结果与预期结果进行比较。如果该方法返回null,那么我将进行设置,因为它尚未完成,然后通过调用ResetCalls(好像我从未检查过该方法的结果

我们都知道,在Moq中,我们可以使用
Setup
模拟该方法。如何检查是否正在设置该方法?我不想调用该方法并检查其结果,因为在
Verify
期间,这将作为对模拟方法的实际调用计算(除非您可以告诉我如何使其不计算-这也将作为一个答案计算)。

实际上,我刚刚找到了
Mock
上定义的
ResetCalls
方法,这将重置计数器。这可能会对我有所帮助,因为我可以调用父方法并将结果与预期结果进行比较。如果该方法返回null,那么我将进行设置,因为它尚未完成,然后通过调用
ResetCalls
(好像我从未检查过该方法的结果)重置计数器。然后我继续进行子设置


我需要注意它的副作用,但在这里发布,以防其他人有同样的问题。我仍然希望找到一个更好的答案,比如可能只重置最后一个调用到mock方法。我当前的发现重置了所有调用,这可能不是我在所有情况下都想要的。

有一个非常脏的反射方法,但它可以工作

using System.Linq;
using System.Linq.Expressions;
using Moq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

public static class MoqExtensions
{
    public static bool WasMethodSetup(this Mock mock, string method)
    {
        var moqSetups = new PrivateObject(new PrivateObject(mock).GetProperty("Setups")).Invoke("ToArray") as object[];
        var moqExpressions = moqSetups.Select(s => new PrivateObject(s).GetProperty("SetupExpression") as LambdaExpression);
        return moqExpressions.Where(e => e.Body.NodeType == ExpressionType.Call)
                .Select(b => new PrivateObject(new PrivateObject(b.Body).GetProperty("Method")).GetProperty("Name"))
                .Contains(method);
    }
}
用法示例

var mock = new Mock<IDisposable>();
mock.Setup(d => d.Dispose());
var b1 = mock.WasMethodSetup("Dispose"); // true
var b2 = mock.WasMethodSetup("666"); // false
var mock=new mock();
mock.Setup(d=>d.Dispose());
var b1=mock.WasMethodSetup(“Dispose”);//真的
var b2=mock.WasMethodSetup(“666”);//假的

当一个单元测试类对另一个进行子类化,并且子类的测试已经使用子类mock进行了设置时,就会出现问题。所以解决这个问题的唯一方法就是设置子类mock来回调您的mock方法。it.Ok(),但有时在回调工作流中,它应该重定向到原始的模拟方法回调。在运行测试下的代码之前,只需搜索如何从这个模拟列表

Setup方法调用它,您就会知道该方法是Setup,这是显而易见的。我有一个特定的场景,我需要检查我是否已经进行了设置。我不相信有任何方法可以看到Moq对什么执行了设置,但我很好奇,对于这种需要,您会有什么用例?我的每一句话都在说“你过度设计了一个单元测试”来满足这一需求,因为模拟本质上意味着在单元测试期间被暗示为设置。我确信这是一个合理的原因,但我真的很好奇单元测试的原因是什么,最好在每次测试之前设置依赖项。似乎您的特定场景将您引入“黑客”解决方案,这是测试设计出问题的好迹象。能举例说明你们的具体情况吗?我同意复杂性投诉。我自己也有这样的抱怨,但有时我们不得不处理我们继承的东西,包括遗留的或不需要的设计。我只是在扩展已经存在的内容。如果该方法返回null,那么我将进行设置,因为它尚未完成-别忘了为您的测试编写单元测试:)对,我们确实为此进行了单元测试,结果是。。。但我完全同意你。