为什么世界上这个Moq + NUnit测试失败了?

时间:2010-04-15 16:51:09

标签: c# nunit moq

我有这个dataAccess模拟对象,我正在尝试验证其中一个方法是否被调用,并且传递给此方法的参数满足某些约束。我可以说,这个方法确实被调用,并且满足了约束条件。测试的这一行抛出一个MockException:

data.Verify(d => d.InsertInvoice(It.Is<Invoice>(i => i.TermPaymentAmount == 0m)), Times.Once());

但是,删除约束并接受任何发票都会通过测试:

data.Verify(d => d.InsertInvoice(It.IsAny<Invoice>()), Times.Once());

我已经创建了一个测试窗体,它实例化了这个测试类,运行了它的.Setup()方法,然后调用了我希望测试的方法。我在模拟对象未通过测试的代码行上插入一个断点

data.InsertInvoice(invoice);

实际将鼠标悬停在发票上,我可以在调用方法时确认其.TermPaymentAmount十进制属性确实为零。

出于绝望,我甚至在我的dataAccess模拟中添加了一个回调:

data.Setup(d => d.InsertInvoice(It.IsAny<Invoice>())).Callback((Invoice inv) => MessageBox.Show(inv.TermPaymentAmount.ToString("G17")));

这会给我一个显示0的消息框。这真让我感到困惑,我店里没有其他人能够解决这个问题。任何帮助将不胜感激。

一个几乎没有相关的问题,我应该独立询问,是否最好像我在这里使用Mock.Verify(),或者使用Mock.Expect()。我可以看到其他人正在进行Mock.VerifyAll()验证吗?如果答案是情境性的,那么哪种情况可能会使用另一种情况呢?

3 个答案:

答案 0 :(得分:0)

只是为了排除这一点(因为我有一些像你这样的奇怪行为:
尝试Times.Exactly(1)而不是Times.Once()。 使用Times.Once()时发生了一些奇怪的事情 虽然,我猜想Once()在内部使用Exactly(1)......

答案 1 :(得分:0)

我使用的是Moq版本3.1.0.0,并且在以下测试用例中没有遇到此问题。

internal class Program
{
    private static void Main(string[] args)
    {
        var mock = new Mock<IData>();
        mock.Setup(d => d.InsertInvoice(It.IsAny<Invoice>()));

        var service = new MyService(mock.Object);
        service.DoSomething(new Invoice());

        mock.Verify(d => d.InsertInvoice(It.Is<Invoice>(i => i.TermPaymentAmount == 0m)), Times.Once());

        Console.ReadLine();
    }
}

internal class MyService
{
    private readonly IData _data;

    public MyService(IData data)
    {
        _data = data;
    }

    public void DoSomething(Invoice invoice)
    {
        _data.InsertInvoice(invoice);
    }
}

public class Invoice
{
    public decimal TermPaymentAmount { get; set; }
}

public interface IData
{
    void InsertInvoice(Invoice invoice);
}

您是否可以提供有关如何使用模拟器的更多信息?

答案 2 :(得分:0)

我的猜测是它可能与浮点值的等效性检查所固有的问题有关。您的Invoice.TermPaymentAmount属性值是否可能是计算结果?

想知道我在说什么,请看这个可能相关的问题: Is it safe to check floating point values for equality to 0?