【问题标题】:C# Nunit Moq Cannot make test passC# Nunit Moq 无法通过测试
【发布时间】:2017-01-17 15:15:11
【问题描述】:

我有这门课:

class MyClass
{
    private ISomeInterface blabla;

    public MyClass() : this(new SomeInterfaceImplementation()) {}

    internal MyClass(ISomeInterface blabla)
    {
        this.blabla = blabla;
    }

    public void SomeMethod(string id, int value1, int value2)
    {
        this.blabla.DoSomethingWith(id, new ValueClass(value1, value2))
    }
}

我也有这个测试:

[TestFixture]
public class MyClassTest
{
    private const string ID = "id";
    private const int VALUE1 = 1;
    private const int VALUE2 = 2;

    private ValueClass valueClass;

    private Mock<ISomeInterface> mockInterface;

    private MyClass myClass;

    [SetUp]
    public void SetUp()
    {
        this.valueClass = new ValueClass(VALUE1, VALUE2);
        this.mockInterface = new Mock<ISomeInterface>();
        this.myClass = new MyClass(this.mockInterface.Object);
    }

    [Test]
    public void GIVEN_AnID_AND_AValue1_AND_AValue2_WHEN_DoingSomeMethod_THEN_TheSomeInterfaceShouldDoSomething()
    {
        this.myClass.SomeMethod(ID, VALUE1, VALUE2);
        this.mockInterface.Verify(m => m.DoSomethingWith(ID, this.valueClass), Times.Once()); //<- Test fails here!
    }
}

我不知道为什么,但我无法通过此测试。 NCrunch 给我以下错误信息:

Moq.MockException : 预期在模拟上调用一次,但为 0 次: m => m.DoSomethingWith("ID", .valueClass) 没有设置 配置好了。

执行的调用:

ISomeInterface.DoSomethingWith("ID", MyNamespace.ValueClass) 在 Moq.Mock.ThrowVerifyException(MethodCall 预期,IEnumerable1 setups, IEnumerable1 actualCalls,Expression 表达式,Times 次, Int32 callCount) 在 Moq.Mock.VerifyCalls(Interceptor targetInterceptor、MethodCall 预期、Expression 表达式、Times 次)在 Moq.Mock.Verify[T](Mock1 mock, Expression1 表达式, 次次,字符串 failMessage) 在 Moq.Mock1.Verify(Expression1 表达式,时代时代)在 Tests.MyClassTest.GIVEN_AnID_AND_AValue1_AND_AValue2_WHEN_DoingSomeMethod_THEN_TheSomeInterfaceShouldDoSomething() 在 C:\MySourceCode\File 和行号在这里。

如您所见,Moq 似乎“看不到”我的调用,可能是因为 new ValueClass(value1, value2) 我怎样才能使这个测试通过或者我怎样才能改变我的设计以便更容易测试?我应该把new ValueClass(value1, value2)放在哪里?

编辑:

这是我应该在软件工程而不是 StackOverflow 上问的问题吗?这超出范围了吗?

【问题讨论】:

  • 它正在尝试比较被测方法中的不同值类。使用It.Any&lt;ValueClass&gt;()。如果您想比较暴露的字段/属性,也可以应用谓词。

标签: c# unit-testing nunit moq ncrunch


【解决方案1】:

您的问题是方法调用中的参数不匹配:this.valueClass 默认不等于new ValueClass(value1, value2),因为它将是ValueClass 的两个不同实例。默认情况下,两个实例将通过引用进行比较,这是不同的。你可以:

  • 覆盖ValueClass 中的EqualsGetHashCode 方法以更改两个实例的比较方式。 IE。按值比较,而不是按引用比较。
  • 使用It.Any&lt;ValueClass&gt;() 忽略此参数。如果您不关心 ValueClass 的特定值而只想检查方法是否被调用,那就太好了。并非总是最佳选择
  • 使用谓词手动检查ValueClass 的值:It.Is&lt;ValueClass&gt;(vc =&gt; vc.Value1 == VALUE1 &amp;&amp; vc.Value2 == VALUE2)。有时它也很好。例如。如果您无法覆盖Equals。但这会降低测试的可读性。

【讨论】:

  • 我只是覆盖(覆盖,覆盖?)ValueClass 的 Equals() 和 GetHashCode()。现在测试通过了!谢谢!
  • 不知道你可以添加谓词!我想我会改用谓词,因为我必须为 Equals() 添加测试,而我不想这样做。
  • @Sebastien 可以,但请记住测试的可重复性。它们会变得非常混乱。还可以想象 - 您有 50 个测试来检查谓词中的值。然后将新字段添加到 ValueClass。使用 Equals,您只需更改重载。使用谓词,您必须更新 50 个测试。
  • 噢噢噢... derpyderp!等于是XD!我不想在每次 ValueClass 更改时都中断我的测试!
猜你喜欢
  • 2015-06-03
  • 1970-01-01
  • 2021-08-25
  • 2012-10-02
  • 2018-08-23
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 2016-09-21
相关资源
最近更新 更多