2009-09-10 2 views
0

Я модульное тестирование код, который interactes с репозиторием, который принимает выражение (Expression<Func<Entity, bool>>), чтобы фильтровать результаты, например, так:Единичное тестирование с помощью выражений?

int orderId = 10; 

_respository.GetFiltered(order => order.Id == orderId); 

Я имею проблему для модульного тестирования, более конкретно настройки ожидания, выражение будет соответствовать. В модульном тесте я хочу сделать это:

_mockRespository.Setup(r => r.GetFiltered(order => order.Id == 10)).Returns(new Order[0]).AtMostOnce(); 

Я нашел одно решение, которое предложило делать .ToString() на каждое выражение и compairing, которые, тем не менее, когда вы ссылаетесь на переменном, например, как OrderId, выражение совершенно иное!

Что люди делают, чтобы проверить это?

Спасибо,

Дэвид

+0

Не уверен, что я понимаю ... вместо передачи выражений методу установки. Что делать, если вы кэшируете его в локальном var и передаете его методу установки. – Gishu

+0

Если вы это сделаете, тогда останется тот же вопрос! Как сравнить, что два выражения одинаковы !? –

ответ

0

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

Что мы делаем, мы не обязательно проверяем, что параметр выражения linq to entity, переданный из типа A (в тесте), использует конкретное дерево выражений при вызове GetFoo() для совместного использования репозитория (не тестируется). Для модульного теста мы довольны проверкой того, что метод GetFoo() вызывает правильную подпись.

В вашем случае это выглядит, как вы используете Moq (?), В этом случае, что стало бы что-то вроде этого (остерегайтесь синтаксиса беспорядке)

_mockRespository.Setup(r => r.GetFiltered(It.IsAny<Expression<Func<Entity, bool>>>())).Returns(new Order[0]).AtMostOnce(); 

Для нас это имеет смысл, потому что а) издевались проверка сравнения параметров метода с параметрами метода действительно является болью и б) даже если бы мы могли проверить, что параметр, который на самом деле интерпретировал бы Б, мог бы изменить различные комбинации значений параметров (как в семантике контракта А-> В), и если это так, сделает испытание хрупким.

Мы используем автоматические тестовые тесты для тестирования взаимодействия между производством A и производством B. Мы считаем, что это лучший способ проверить эти сценарии, поскольку они, как правило, что-то вроде «отфильтровать все A в хранилище в соответствии с выражением X и дать мне все объекты, которые соответствуют '. Для нас это имеет смысл как интеграционные тесты (достаточно одного или двух счастливых случаев).

Если вам этого не достаточно, я бы зачитал: a) как создать пользовательские маркеры Moq, хотя я не могу точно сказать, что есть простое решение (может быть, очень хорошо) или b) настраивая обратные вызовы ожидания, чтобы вы могли зафиксировать параметр и проверить его после теста. Что-то вроде этого:

Expression<Func<Entity, bool>> actualExpression = null; 
    _mockRespository.Setup(r => r.GetFiltered(It.IsAny<Expression<Func<Entity, bool>>>())).Returns(new Order[0]).AtMostOnce().Callback((Expression<Func<Entity, bool>> expr => { actualExpression = expr}); 

    // exercise production code 

    Assert.IsTrue(actualExpression ...... someithing clever here); 

Примечание: весь выше код был написан в редакторе переполнения стека. Не держите меня ответственным, если он не компилируется, документы Moq охватывают это

Смежные вопросы