2017-01-22 9 views
1

Я новичок, чтобы написать Unit Tests. Поэтому я боролся.Проблема в модульных испытаниях и использовании Moq. Возвраты

Мне нужно вставить продукт через внешний WebService. Затем WebService вернет строку, необходимую для обновления продукта.

Это мой ApiController:

public class ProductController : ApiController 
{ 
    private IProductRepository _ProductRepository; 
    private IWebService _WebService; 

    public ProductController(IProductRepository productRepository, IWebService webService) 
    { 
     _ProductRepository = productRepository; 
     _WebService = webService; 
    } 

    public HttpResponseMessage Add(string title) 
    { 
     using (TransactionScope scope = new TransactionScope()) 
     { 
      Product product = new Product 
      { 
       Title = title 
      }; 

      this._ProductRepository.Add(product); 

      // WebService will return a string 
      string result = this._WebService.Add(product.ID, DateTime.Now); 

      product.ServiceResult = result; 

      this._ProductRepository.Update(product); 

      scope.Complete(); 
     } 

     return Request.CreateResponse(HttpStatusCode.Created); 
    } 
} 

мне было интересно, как я должен написать модульный тест для этого кода?

Я попытался написать это следующим образом: (с NUnit, MOq)

[TestFixture] 
public class ProductControllerShould : AssertionHelper 
{ 
    private Mock<IWebService> _WebService; 
    private Mock<IProductRepository> _ProductRepository; 

    [SetUp] 
    public void Setup() 
    { 
     _WebService = new Mock<IWebService>(); 
     _ProductRepository = new Mock<IProductRepository>(); 
    } 

    [Test] 
    public void ReturnCreatedOnAdd() 
    { 
     _WebService.Setup(b => b.Add(1, DateTime.Now)) 
      .Returns("0"); 

     var controller = new ProductController(_ProductRepository.Object, 
         _WebService.Object); 

     var result = controller.Add("Lumia"); 

     Expect(result, Is.EqualTo(HttpStatusCode.Created)); 
    } 
} 

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

string result = this._WebService.Add(product.ID, DateTime.Now); 

Не должна ли эта строка обрабатывать поведение _WebService.Add() и возвращать «0»?

_WebService.Setup(b => b.Add(1, DateTime.Now)) 
       .Returns("0"); 

Я знаю, что я пишу тест неправильно, но я не знаю, что мне делать.

Спасибо.

ответ

3

Проблема в том, что вы издеваетесь над вызовом статического метода `DateTime.Now '. Но «сейчас» в момент насмешливости и, как его называют, разные. Поэтому ваш звонок ничего не возвращает.

я мог бы предложить три следующих способа:

1) Это действительно не имеет значения для вас, если вызов был с DateTime.Now или нет, в этом случае вы можете игнорировать второй аргумент:

_WebService.Setup(b => b.Add(1, It.IsAny<DateTime>())).Returns("0"); 

2) Вы хотите проверить, что звонок был с DateTime.Now. В этом случае я создать interface для получения DateTime.Now:

public interface IDateTimeNowProvider 
{ 
    DateTime Now { get; } 
} 

public ProductController(IProductRepository productRepository, 
        IWebService webService, 
        IDateTimeNowProvider dateTimeNowProvider) 
{ 
    _ProductRepository = productRepository; 
    _WebService = webService; 
    _dateTimeNowProvider = dateTimeNowProvider; 
} 

В производстве код используется реализация его по умолчанию, то просто возвращает D ateTime.Now. Но в вашем тестовом классе вы издеваетесь над этим интерфейсом с некоторыми предопределенными значениями, и вы проверяете использование этого значения.

var now = DateTime.Parse("2017-01-22"); 
var _dateTimeNowProvider = new Mock<IDateTimeNowProvider>(); 
var controller = new ProductController(_ProductRepository.Object, 
         _WebService.Object, _dateTimeNowProvider.Object); 
_dateTimeNowProvider.Setup(x => x.Now).Returns(now); 
_WebService.Setup(b => b.Add(1,now)).Returns("0"); 

3) Вы можете использовать специальные насмешливый рамки, что позволяет издеваться статические методы, как, например, typemock isolator

+0

Спасибо @Maksim. Я этого не знал. Это был отличный момент. Тем не менее, я применил изменения, но все равно результат равен нулю. –

+0

@NavidKh, что вы использовали? –

+0

Решения № 1 и 2 –