簡體   English   中英

用屬性返回替換,用N替換值的集合

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM