nUnit / moq - почему мой макет всегда возвращает false? - PullRequest
0 голосов
/ 26 февраля 2019

Я новичок в модульном тестировании с nUnit и Moq и столкнулся с проблемой установки поведения для метода в dbprovider.

Я пытаюсь проверить метод проверки, который вызывает метод Exists вICoDbProvider.Если false, метод генерирует исключение, и он работает хорошо.При значении true метод должен выполняться до оператора return true; в конце метода.

Это проверенный метод:

private bool ValidateReciboCajaModel(ReciboCajaModel model)
{
        if (model == null)
            throw new ArgumentException("El modelo ha llegado nulo");

        if (string.IsNullOrWhiteSpace(model.AccionARealizar))
            throw new ArgumentException("No se ha definido una Acción a realizar");

        if (!_accionARealizarService.Exists(new AccionARealizarEntity(model)))
            throw new ArgumentException(@"No es una ""acción a realizar"" válida");


        if (string.IsNullOrWhiteSpace(model.CentroCostos))
            throw new ArgumentException("No se ha definido ningún centro de costos");

        if (!_centroCostosService.Exists(new CentroCostosEntity(model)))
            throw new Exception("No es un centro de costos válido");

        if (String.IsNullOrWhiteSpace(model.CuentaIngresoDinero))
            throw new Exception("No es una cuenta de Ingreso válida");

        if (!_terceroService.Exists(new TerceroEntity(model)))
            throw new Exception("No es un tercero registrado");

        if (String.IsNullOrWhiteSpace(model.Tercero))
            throw new Exception("No es un tercero válido");

        if (!_tipoReciboCajaService.Exists(new TipoReciboCajaEntity(model)))
            throw new Exception("No es un recibo de caja registrado");

        if (String.IsNullOrWhiteSpace(model.TipoReciboCaja))
            throw new Exception("No es un recibo de caja válido");

        if (!(0 < model.ValorPagado && model.ValorPagado <= 999999999999d))
            throw new Exception("El valor pagado no es válido");

        return true;

}

ПроверкаПервоначально был сгенерирован Intellitest и создал леса для тестирования закрытых методов.

Метод теста выглядит следующим образом.

    [Test]
    [PexGeneratedBy(typeof(ReciboCajaBizTest))]
    [PexRaisedException(typeof(TargetInvocationException))]
    public void ValidateReciboCajaModel_ValidModel()
    {
        bool b;
        TargetInvocationException receivedException = new TargetInvocationException(null);

        ReciboCajaModel s1 = new ReciboCajaModel();
        var accionARealizarService = new Mock<ICoDbProvider>();
        var centroCostosService = new Mock<ICoDbProvider>();
        var terceroService = new Mock<ICoDbProvider>();
        var tipoReciboCajaService = new Mock<ICoDbProvider>();

        s1.TipoReciboCaja = "RC0";
        s1.Numero = 0;
        s1.Tercero = "tercero existente";
        s1.AccionARealizar = "some action";
        s1.FechaElaboracion = default(DateTime);
        s1.CentroCostos = "cc1";
        s1.CuentaIngresoDinero = "Débito";
        s1.ValorPagado = 1000000d;

        accionARealizarService.Setup(m => m.Exists(new AccionARealizarEntity(s1))).Returns(true);
        centroCostosService.Setup(m => m.Exists(new CentroCostosEntity(s1))).Returns(true);
        terceroService.Setup(m => m.Exists(new TerceroEntity(s1))).Returns(true);
        tipoReciboCajaService.Setup(m => m.Exists(new TipoReciboCajaEntity(s1))).Returns(true);

        ReciboCajaBiz s0 = new ReciboCajaBiz(null, accionARealizarService.Object, centroCostosService.Object,terceroService.Object,tipoReciboCajaService.Object);

        b = this.ValidateReciboCajaModel(s0, s1);

        Assert.AreEqual(true, b);
    }

В этом случае все в модели правильно, и метод должен возвращать действительный флаг.

У меня странное поведение при отладке.Сразу после установки поведения Mocks я вызвал в окне Watch метод, и он вернул false, как показано на рисунке

debug shows the behaviour is not working as set

У меня также есть метод, которыйпроверяет, что объект accionARealizar не существует, и он возвращает false как установлено.Но я сомневаюсь, что он работает правильно.

Обновление

Как указано в комментариях ниже, это конструкторы ReciboCajaModel

public class ReciboCajaModel
{
    [Required]
    [EnumDataType(enumType: typeof(TipoReciboCaja))]
    public string TipoReciboCaja { get; set; }
    [Required]
    public int Numero { get; set; }
    [Required]
    public string Tercero { get; set; }
    [Required]
    public string AccionARealizar { get; set; }
    [Required]
    public DateTime FechaElaboracion { get; set; }
    [Required]
    public string CentroCostos { get; set; }
    /// <summary>
    /// este campo no sólo enlaza la cuenta donde se hace el abono o accion a realizar, sino también la forma de pago
    /// </summary>
    [Required]
    public string CuentaIngresoDinero { get; set; }
    [Required]
    [Range(0, 999999999999)]
    public double ValorPagado { get; set; }
}

и ReciboCajaBiz и частныеучастники

    private ICoDbProvider _reciboCajaService;
    private ICoDbProvider _accionARealizarService;
    private ICoDbProvider _centroCostosService;
    private ICoDbProvider _terceroService;
    private ICoDbProvider _tipoReciboCajaService;

    public ReciboCajaBiz()
    {
        _reciboCajaService = new ReciboCajaService();
        _accionARealizarService = new AccionARealizarService();
    }

    public ReciboCajaBiz(ICoDbProvider reciboCajaService = null, ICoDbProvider accionARealizarService = null, ICoDbProvider centroCostosService = null, ICoDbProvider terceroService = null, ICoDbProvider tipoReciboCajaService = null)
    {
        _reciboCajaService = reciboCajaService == null ? new ReciboCajaService() : reciboCajaService;
        _accionARealizarService = accionARealizarService == null ? new AccionARealizarService() : accionARealizarService;
        _centroCostosService = centroCostosService == null ? new CentroCostosService() : centroCostosService;
        _terceroService = terceroService == null ? new TerceroService() : terceroService;
        _tipoReciboCajaService = tipoReciboCajaService == null ? new TipoReciboCajaService() : terceroService;
    }

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Проблема заключалась в использовании ссылок на объекты в наборе поведения макета.Я использовал это:

accionARealizarService.Setup(m => m.Exists(new AccionARealizarEntity(s1))).Returns(true);

Но это заставит тест создать объект и сравнить этот объект с объектом, отправленным в метод Exists, чтобы он мог проверить поведение.Это вызовет метод Equals и, следовательно, всегда выдаст false.

Для правильной проверки параметров, отправляемых в проверяемый метод, я должен использовать это:

accionARealizarService.Setup(m => m.Exists(It.IsAny<CoEntity>())).Returns(true);

Оператор It.IsAny<CoEntity> будет указывать на поведение смоделированного метода не для сравнения с конкретным экземпляром объекта, а для проверки, является ли объект CoEntity.

Я пришел к такому выводу и опубликовал полный ответ на основе @Ответ Ральфа, который привел меня на правильный путь.

0 голосов
/ 26 февраля 2019

На первый взгляд, ваши выражения Moq могут не совпадать, как вы ожидаете.

Вы пытаетесь сопоставить ссылку на объект для вашей функции Exists (), что означает, что она выполнит проверку на равенство объектассылки - которые не будут совпадать.Вы создаете два разных объекта.

_accionARealizarService.Exists(new AccionARealizarEntity(model))

Подробнее об аргументах сопоставления Moq см. Здесь

Измените выражение макета Setup, чтобы оноболее щедрым, чтобы увидеть, если это проблема.

Вы можете использовать It.IsAny() в выражении как.

accionARealizarService.Setup(m => m.Exists(It.IsAny<SiigoEntity>())).Returns(true);

Как только это сработает, вы можете получить более конкретную информацию с помощью It.Is()Выражение, для проверки свойства объекта.

...