Почему в мире этот тест Moq + NUnit не проходит? - PullRequest
0 голосов
/ 15 апреля 2010

У меня есть этот фиктивный объект 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 голосов
/ 15 апреля 2010

Я использую 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);
}

Не могли бы вы предоставить немного больше информации о том, как вы используете макет?

0 голосов
/ 19 апреля 2010

Я предполагаю, что это может быть связано с проблемами, связанными с проверкой эквивалентности значений с плавающей запятой. Может быть, ваше Invoice.TermPaymentAmount значение свойства является результатом вычисления?

Чтобы понять, о чем я говорю, посмотрите этот, возможно, связанный вопрос: Безопасно ли проверять значения с плавающей точкой на равенство 0?

0 голосов
/ 15 апреля 2010

Просто чтобы исключить это (потому что у меня странное поведение, как у вас:
Попробуйте Times.Exactly (1) вместо Times.Once (). У меня была какая-то странная вещь, происходящая при использовании Times.Once () Хотя я бы догадался, что Once () использует Exactly (1) для внутреннего использования ...

...