2014-01-21 4 views
161

У меня есть интерфейс, который декларируетНастройка задачи асинхронных обратный вызов в MOq Framework

Task DoSomethingAsync(); 

Я использую MoqFramework для моих тестов:

[TestMethod()] 
public async Task MyAsyncTest() 
{ 
    Mock<ISomeInterface> mock = new Mock<ISomeInterface>(); 
    mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> }); 
    ... 
} 

Тогда в моем тесте я выполнить код, который вызывает await DoSomethingAsync(). И тест просто терпит неудачу на этой линии. Что я делаю не так?

+4

Когда вы говорите ошибки тестирования на эту линии, какую ошибку она производит? – AlSki

ответ

353

Ваш метод не имеет обратных вызовов, поэтому нет причин использовать .CallBack(). Вы можете просто вернуть задачу с желаемые значения с помощью .Returns() и Task.FromResult и т.д .:

MyType someValue=...; 
mock.Setup(arg=>arg.DoSomethingAsync())   
    .Returns(Task.FromResult(someValue)); 

Обновление 2014-06-22

Moq 4.2 имеет два новых методов расширения, чтобы помочь с этим.

mock.Setup(arg=>arg.DoSomethingAsync()) 
    .ReturnsAsync(someValue); 

mock.Setup(arg=>arg.DoSomethingAsync())   
    .ThrowsAsync(new InvalidOperationException()); 

Обновление 2016-05-05

Как Сет Цветы упоминает в other answer, ReturnsAsync доступен только для методов, которые возвращают Task<T>. Для методов, возвращающих только задание,

.Returns(Task.FromResult(default(object))) 

может использоваться.

Как показано в this answer, в .NET 4.6 это упрощено до .Returns(Task.CompletedTask);, например:

mock.Setup(arg=>arg.DoSomethingAsync())   
    .Returns(Task.CompletedTask); 
+0

Он решил проблему. Спасибо! – Waldemar

+6

. Возвраты (Task.CompletedTask); это был мой ответ –

+3

ReturnsAsync отлично работает. – Sully

28

Похожие Issue

У меня есть интерфейс, который выглядел примерно так:

Task DoSomething(int arg); 

Симптомы

Мой модульный тест завершился неудачно, когда мой сервис под тестированием awaited позвонил по телефону DoSomething.

Fix

В отличие от принятого ответа, вы не можете позвонить .ReturnsAsync() на вашем Setup() этого метода в этом случае, так как метод возвращает необщего Task, а не Task<T>.

Тем не менее, вы по-прежнему можете использовать .Returns(Task.FromResult(default(object))) на настройке, позволяя пройти тест.

+1

Просто подумайте об этом, если вам нужно вернуть не-общую задачу (non .net 4.6), я бы рассмотрел возможность возврата Task.Delay (1) в качестве простого способа вернуть задачу. Вы также можете имитировать работу, увеличив аргумент времени. – stevethethread

13

Вам нужно только добавить .Returns(Task.FromResult(0)); после обратного вызова.

Пример:

mock.Setup(arg => arg.DoSomethingAsync()) 
    .Callback(() => { <my code here> }) 
    .Returns(Task.FromResult(0)); 
Смежные вопросы