C# Moq-测试在独立执行时运行正常,但在连续执行时失败

C# Moq-测试在独立执行时运行正常,但在连续执行时失败,c#,unit-testing,moq,C#,Unit Testing,Moq,我们正在使用Moq来执行一些单元测试,其中有一些奇怪的行为,可能是我遗漏了一些配置问题 基本上,我有两个测试(它们调用windows工作流,调用使用Invoke调用方法的自定义活动。我不知道这是否有帮助,但我想提供尽可能多的信息)。单独执行测试时运行正常,但如果我在同一次运行中执行测试,第一个测试通过,第二个测试失败(无论我是否更改测试顺序,第二个测试总是失败) 每次都会使用Unity重新创建模拟。例: MockProcessConfigurator = MockFactory.Create&l

我们正在使用Moq来执行一些单元测试,其中有一些奇怪的行为,可能是我遗漏了一些配置问题
基本上,我有两个测试(它们调用windows工作流,调用使用Invoke调用方法的自定义活动。我不知道这是否有帮助,但我想提供尽可能多的信息)。单独执行测试时运行正常,但如果我在同一次运行中执行测试,第一个测试通过,第二个测试失败(无论我是否更改测试顺序,第二个测试总是失败)

每次都会使用Unity重新创建模拟。例:

MockProcessConfigurator = MockFactory.Create<IProcessConfigurator>();
 MockProcessConfigurator.Setup(x => x.MyMethod(It.IsAny<Order>()));
[...]
InversionOfControl.Instance.Register<IProcessConfigurator>(MockProcessConfigurator .Object)
调用(调用的调用)是

调试时,我看到ProcessConfigurator总是被模拟的

测试中失败的调用非常简单:

MockEnvironment.MockProcessConfigurator.Verify(x => x.MyMethod(It.IsAny<Order>()), Times.Exactly(1));
MockEnvironment.MockProcessConfigurator.Verify(x=>x.MyMethod(It.IsAny()),Times.justice(1));

在调试时,实际上每次都会调用该方法,因此我怀疑模拟实例中存在问题。我在这里有点不知所措,因为事情似乎得到了正确的实现,但由于某种原因,当它们一个接一个地运行时,会出现一个问题

当两个测试共享某些内容时,通常会发生这种类型的错误

例如,您在设置模拟时期望在测试设置中调用一次方法,然后两个测试每次调用该方法一次-您的期望将失败,因为它现在已被调用两次


这表明你应该将期望值的设置转移到每个测试中。

要扩展给出的答案,我会检查我的设置/拆卸方法,以确保你正确地整理了所有内容。在批量运行测试而没有整理模拟对象时,我也遇到过类似的问题。

解决此类问题的一般方法是尝试隔离两个测试之间的依赖关系

  • 将任何设置代码移到测试内部
  • 将任何分解代码移到测试内部
  • 将所有字段初始值设定项移动到测试内部。(每个夹具只运行一次!)
  • 这将使两个测试在一起运行时通过。当你得到绿灯时,你可以开始再次将重复的东西移到初始化器/设置器中,每次更改后运行测试


    您应该能够了解导致测试之间耦合的原因。祝你好运

    我不知道这是否相关,但是MockFactory.Create看起来很奇怪。我通常按如下方式创建模拟:

    var mockProcessConfigurator = new Mock<IProcessConfigurator>();
    
    在MockFactory上调用静态方法似乎无法达到目的。如果您有一个非标准的命名约定,其中MockFactory实际上是MockFactory类型的变量,那么这可能不是您的问题(但会经常引起混淆)。如果MockFactory是测试类的属性,请确保在安装程序中重新创建它

    如果可能的话,我会消除工厂,因为它是共享状态的潜在来源


    编辑:作为备用WorkflowInvoker。Invoke将活动作为参数。您可以只传递自定义活动的实例,而不是创建整个工作流来测试自定义活动。如果这就是您想要测试的,那么它会使您的单元测试更加集中。

    认为我应该添加一个我刚刚遇到的额外情况和解决方案:

    如果您同时从两个独立的项目运行测试,并且每个项目都使用不同版本的Moq,那么同样的问题也会发生

    对我来说,我让TestProjectA使用Moq 4.2.14,TestProjectB在事故中使用Moq 4.2.15(由Nuget提供)。同时从a和B运行测试时,第一个测试成功,第二个测试失败


    调整两个项目以使用相同的版本解决了问题。

    您是为每个测试创建MOQ对象的实例,还是重复使用?您还可以添加一些关于测试如何失败的细节,以及失败方法中的一些代码。每次之后都会重新创建所有内容。另外,在第二次测试运行中,它说该方法被调用了0次。我现在也有同样的问题。这个答案没有意义,因为测试(默认情况下)总是在单个线程中一个接一个地执行,并且上下文应该重新创建。。
    MockEnvironment.MockProcessConfigurator.Verify(x => x.MyMethod(It.IsAny<Order>()), Times.Exactly(1));
    
    var mockProcessConfigurator = new Mock<IProcessConfigurator>();
    
    var factory = new MockFactory(MockBehavior.Strict) { DefaultValue = DefaultValue.Mock };