2016-05-19 2 views
0

Это интерфейс IValidationResultЗаменитель С возвращением собственности и коллекции со значениями с NSubstitute

public interface IValidationResult 
{ 
    ICollection<IValidationError> Errors { get; } 
    bool IsValid { get; } 

    IValidationResult Add(IValidationError error); 
    IValidationResult Add(string errorMessage); 
    IValidationResult Add(params IValidationResult[] validationResults); 
    IValidationResult Remove(IValidationError error); 
} 

У меня есть этот метод испытания

[TestMethod] 
public async Task ServicoDeveRetornarFalseCasoHajaErroNaCriacaoDoObjeto() 
{ 
    // arrange 
    var validation = Substitute.For<IValidationResult>(); 
    validation.IsValid.Returns(false); 
    _contratoFactory.Build(ContratoValues.ContratoComEmpresaNula).Returns(validation); 

    // act 
    var result = await _contratoService.Create(ContratoValues.ContratoComEmpresaNula); 

    // assert 
    result.Success.Should().BeFalse(); 
} 

«проверки» заменить это Мок из IValidationResult. Этот интерфейс реализует свойство, называемое IsValid, которое возвращает false - это еще одно свойство, то есть Collection содержит любой элемент.

Мой метод испытания должен убедиться, что при

_contratoFactory.Build(any) 

называется, она возвращает IValidationResult, который не является действительным.

Затем результат _contratoService.Create(any) должен быть false.

Мой макет не работает.

Как это исправить?

UPDATE - Добавить Создать Реализация

public override async Task<IServiceOperationResult> Create(Contrato entity) 
{ 
    var result = new ServiceOperationResult(); 
    try 
    { 
     if (entity == null) 
     { 
      throw new ArgumentNullException(typeof(Contrato).Name); 
     } 

     var validation = _contratoFactory.Build(entity); 
     result.Add(validation); 

     if (!result.Success) 
     { 
      return result; 
     } 

     return await base.Create(entity); 
    } 
    catch (ArgumentNullException ex) 
    { 
     result.Add(ex); 
    } 
    catch (Exception ex) 
    { 
     result.Add(ex); 
    } 

    return result; 
} 

ОБНОВЛЕНИЕ - 20/05/2015

Вот реализация IServiceOperationResult

public class ServiceOperationResult : IServiceOperationResult 
{ 
    public ServiceOperationResult() 
    { 
     Errors = new Dictionary<string, string>(); 
    } 

    public IDictionary<string, string> Errors { get; } 

    public bool Success => !Errors.Any(); 

    public void Add(string errorMessage) 
    { 
     if (errorMessage == null || errorMessage.Trim().Length == 0) 
     { 
      return; 
     } 

     Errors.Add(Guid.NewGuid().ToString(), errorMessage); 
    } 

    public void Add(IValidationResult validationResult) 
    { 
     if (validationResult == null) 
     { 
      return; 
     } 

     foreach (var validationError in validationResult.Errors) 
     { 
      Add(validationError); 
     } 
    } 

    public void Add(IValidationError validationError) 
    { 
     if (string.IsNullOrEmpty(validationError?.Message) || 
      string.IsNullOrWhiteSpace(validationError.Message)) 
     { 
      return; 
     } 

     Errors.Add(Guid.NewGuid().ToString(), validationError.Message); 
    } 

    public void Add(Exception exception) 
    { 
     if (exception == null) 
     { 
      return; 
     } 
     Add($"{nameof(exception)} - {exception.Message}{Environment.NewLine} - {exception.StackTrace}"); 
    } 
} 
+0

Вы сказали, что 'IsValid' должен возвращать' true' однако, вы установите его, чтобы вернуть 'false':' validation.IsValid.Returns (ложь); ' –

+0

Прошу прощения. Я описал это неправильно. 'IsValid' должен возвращать false. – Jedi31

+0

Пожалуйста, добавьте реализацию метода 'Create' .... –

ответ

0

Проблема, кажется, проистекают из ServiceOperationResult.Add(IValidationResult validationResult):

public void Add(IValidationResult validationResult) 
    { 
     if (validationResult == null) { return; } 

     foreach (var validationError in validationResult.Errors) 
     { 
      Add(validationError); 
     } 
    } 

Это полагается на коллекцию validationResult.Errors, но вы ее не заглушили.

Если изменить тест на что-то вроде следующего должно пройти:

 // arrange 
     var validation = Substitute.For<IValidationResult>(); 
     validation.IsValid.Returns(false); 
     validation.Errors.Returns (new List<IValidationError>()); 
     validation.Errors.Add (new ValidationError { Message = "sample error" }); 
     _contratoFactory.Build(ContratoValues.ContratoComEmpresaNula).Returns(validation); 
     // act ... 

Однако из того, что я могу видеть, в этом случае я бы предложил не притворяется IValidationResult, но используя реальный, как реализация зависит от реального поведения реализации этого интерфейса.

Это сделает тест больше похож:

 // arrange 
     var validation = new ValidationResult>(); 
     validation.Errors.Add (new ValidationError { Message = "sample error" }); 
     // I'm guessing for the real class `validation.IsValid` will now return `false` 
     _contratoFactory.Build(ContratoValues.ContratoComEmpresaNula).Returns(validation); 
     //act... 
+0

Я пробовал ... Но все равно не получается. Кажется, что когда _factory.Build() возвращает, он не возвращает конкретный ValidationResult, а прокси, а коллекция ошибок не загружается. Если он имеет значение 0, то метод успеха IServiceOperationResult вернет false ... И тест завершится неудачно ... – Jedi31

+0

Пример проходящей версии этого теста, используя первый подход в этом ответе: https: //gist.github. ком/dtchepak/7e61de157040279ca6c5349dfa282a28 –

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