2016-12-08 11 views
2

Я новичок в тестировании с помощью Moq, поэтому я немного смущен относительно ReturnsAsync. Вот мой метод тестирования, где я ожидаю, что ReturnsAsync должен получить тип, который будет возвращен методом, определенным в Setup. Я прав?Moq WebApi async method

Но, казалось, ReturnsAsync должен иметь другую подпись - он ищет Func делегат.

[TestClass] 
public class TourObjectControllerTest 
{ 
    [TestMethod] 
    public async Task GetTourObjects() 
    { 
     var mockService = new Mock<ITourObjectService>(MockBehavior.Default); 
     mockService.Setup(x => x.GetAll()).ReturnsAsync(new Task<IEnumerable<TourObjectDTO>>); 
     var controller = new TourObjectController(mockService.Object); 
     var result = await controller.Get(); 
     Assert.IsNotNull(result); 
     Assert.AreSame(typeof(TourObjectViewModel), result); 
    } 
} 

Метод тестируемой:

public async Task<IEnumerable<TourObjectViewModel>> Get() 
{ 
    IEnumerable<TourObjectViewModel> viewmodel = null; 
    try 
    { 
     var tourobjects = await _tos.GetAll(); 
     viewmodel = Mapper.Map<IEnumerable<TourObjectViewModel>>(tourobjects); 
    } 
    catch (Exception ex) 
    { 
     Log.ErrorFormat("Method:{0} <br/> Error: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, ex); 
    } 
    return viewmodel; 
} 
+0

Что говорит Intellisense? (Я предполагаю, что вы работаете в VS.) –

+0

@KennethK., Это говорит, что Task > не может быть назначен для типа Func > –

ответ

1

Передача фактического результата.

Предполагая, что ITourObjectService.GetAll() возвращает Task<IEnumerable<TourObjectDTO>>

например

[TestClass] 
public class TourObjectControllerTest 
{ 
    [TestMethod] 
    public async Task GetTourObjects() 
    { 
     var fakeData = new List<TourObjectDTO>() { 
      new TourObjectDTO { ... } 
     }; 
     var mockService = new Mock<ITourObjectService>(MockBehavior.Default); 
     mockService.Setup(x => x.GetAll()).ReturnsAsync(fakeData); 
     var controller = new TourObjectController(mockService.Object); 
     var result = await controller.Get(); 
     Assert.IsNotNull(result); 
     Assert.IsTry(typeof(IEnumerable<TourObjectViewModel>).IsAssignableFrom(result.GetType()); 
    } 
} 
+0

Пожалуйста, исправьте меня, если я ошибаюсь, Moq генерирует случайные данные типа IEnumerable ? –

+1

Нет, нет. не без какого-либо расширения или плагина – Nkosi

+0

Ну, так как это имитирует поведение репозитория/службы? –

1

ReturnsAsync() следует принимать возвращаемое значение в качестве параметра Я вместо Task<TReurnValue>. Например, следующие 2 строки кода равны (по поведению):

mockService.Setup(x => x.GetAll()).ReturnsAsync(new List<TourObjectDTO>()); 
mockService.Setup(x => x.GetAll()).Returns(Task.FromResult(new List<TourObjectDTO>())); 

Вы должны заменить new List<TourObjectDTO>() с вашими тестовыми данными, которые вы хотите получить в тесте с издеваться. Например, вы можете создать только несколько тестовых значений:

var testData = new [] { new TourObjectDTO(1, "test1"), new TourObjectDTO(2, "test2") }; 
mockService.Setup(x => x.GetAll()).ReturnsAsync(testData); 

или создать при необходимости поддельный генератор данных.

Отметьте, что ReturnsAsync() доступен только для методов, возвращающих Task<T>. Для методов, возвращающих только Task, можно использовать .Returns(Task.FromResult(default(object))).

+0

Да, метод GETALL вернуть Task > –

+0

@ andrey.shedko ok, то просто передайте ожидаемое значение для этого метода в качестве параметра ReturnsAsync или используйте Returns with Task.Result, как в приведенном выше коде. –