代码之家  ›  专栏  ›  技术社区  ›  Ricker Silva

nUnit/moq-为什么我的mock总是返回false?

  •  1
  • Ricker Silva  · 技术社区  · 7 年前

    我对nUnit和Moq的单元测试还比较陌生,在dbprovider中遇到了一个设置方法行为的问题。

    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);
        }
    

    在这种情况下,模型中的所有内容都是正确的,方法应该返回一个有效的标志。

    debug shows the behaviour is not working as set

    我还有一个方法测试accionARealizar对象不存在,并且它返回false作为set。但我怀疑它是否正常工作。

    如以下评论所要求的,这是Reciboajamodel

    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; }
    }
    

    以及Reciboajabiz构造函数和私有成员

        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;
        }
    
    1 回复  |  直到 7 年前
        1
  •  5
  •   Nkosi    7 年前

    乍一看,您的Moq表达式可能与您期望的不匹配。

    您正在尝试匹配Exists()函数的对象引用,这意味着它将对不匹配的对象引用执行相等性检查。你在换两个不同的东西。

    _accionARealizarService.Exists(new AccionARealizarEntity(model))
    

    See here for more info on Moq Matching Arguments

    更改 Setup 所以更大方地看这是否是问题所在。

    It.IsAny()

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

    一旦成功了,你就可以用 It.Is()

        2
  •  1
  •   Nkosi    7 年前

    问题是在mock的行为集中使用对象引用。我在用这个:

    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 .

    推荐文章