这是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();
}
&#34;验证&#34;替代是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;
}
更新 - 2015年5月20日
以下是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 :(得分: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...