[英]Substitute With Property return and Collection with values with NSubstitute
這是一個IValidationResult
接口
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
。
我的模擬無法正常工作。
我該如何解決?
更新-添加創建實施
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}");
}
}
該問題似乎源於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...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.