2010-04-15 4 views
0

У меня есть этот объект dataAccess mock, и я пытаюсь проверить, что один из его методов вызывается, и что аргумент, переданный в этот метод, выполняет определенные ограничения. Насколько я могу судить, этот метод действительно вызывается и с соблюдением ограничений. Эта строка теста бросает MockException:Почему в мире этот тест Moq + NUnit не работает?

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(), как я видел других людей? Если ответ ситуативный, какие ситуации могут привести к использованию одного над другим?

+0

Какую версию Moq вы используете? –

+0

Марк - ты поймал меня на бета-версии 4.0 без ее реализации, хотя я перешел на 3.1.0.0, и у меня все еще такая же проблема. – 2010-04-15 17:52:42

+0

Я могу добавить, что я опробовал это из отчаяния: data.Setup (d => d.InsertInvoice (It.Is (i => i.TermPaymentAmount! = 0))). Броски (новое исключение ArgumentException («TermPaymentAmount») не было 0! ")); , и он ведет себя так, как ожидалось, и не выбрасывает это исключение, потому что Invoice.TermPaymentAmount = 0.(И это порождает исключение, когда я меняю сравнение на! = 0.) Таким образом, это выполняет ту же проверку, к которой я изначально стремился, хотя я не могу понять, почему мой первоначальный метод не работает. – 2010-04-21 18:37:17

ответ

0

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

+0

Это было хорошее предложение, но в этом случае оно не решило проблему. Спасибо хоть! – 2010-04-15 17:53:05

0

Я использую версию 3.1.0.0 от Moq и не испытываю эту проблему со следующим тестовым примером.

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

Я использую макет почти так же, как ты, Марк. Спасибо, что нашли время, чтобы собрать это вместе. Я вижу только некоторые тонкие различия, которые не должны иметь значения: 1. Я не называю mock.Setup(), как вы это делали, - я использую свободное поведение и просто пытаюсь проверить, что метод .InsertInvoice() был вызван. Я вызвал mock.Setup(), чтобы добавить этот отчаянный обратный вызов, но это произошло после возникновения этой проблемы. 2. Есть и другие тонкие отличия (объект счета-фактуры создается ранее в моем коде), хотя я еще не нашел ничего, что должно иметь значение. – 2010-04-15 18:09:33

+0

Каково сообщение об исключении, которое вы получаете? Является ли это чем-то вроде "" \ r \ n Ожидаемое обращение к макету один раз, но было 0 раз: d => d.InsertInvoice (It.Is (i => (i.TermPaymentAmount = 0))) "Или это что-то другое? –

0

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

Для идеи о том, что я говорю, увидеть это, возможно, связанный с этим вопрос: Is it safe to check floating point values for equality to 0?

+0

Это отличное предложение, которое также рекомендовало мне несколько коллег. Invoice.TermPaymentAmount является десятичной, и это результат вычисления, хотя в моем тесте это результат добавления нескольких других нулевых значений друг к другу и когда я фактически запускаю тест в своей среде IDE и когда добавляю метод обратного вызова в MessageBox. Покажите значение, все это выглядит как 0, без минимального десятичного числа. Я пробовал проверить, равна ли значение 0, 0 м, использовать Decimal.Equals и т. Д., Но я не могу пройти этот тест. – 2010-04-21 14:54:06

+0

Я также пытался проверить, является ли Math.Round (invoice.TermPaymentAmount, 4) == 0, и это не работает. Кажется, что насмешливая библиотека будет настаивать на том, что этот тест (в частности, вызов mock.Verify()) не сработает, несмотря ни на что. Я обязательно уточню этот вопрос, когда придумаю ответ! Благодаря! – 2010-04-21 15:01:56