zoukankan      html  css  js  c++  java
  • .net测试篇之Moq行为配置

    系列目录

    我们前面说过.Moq在创建模拟对象的时候,简单对象赋值默认值,引用对象赋值为null,但是有些时候接口里面还包含另一个接口对象,我们知道Moq是可以模拟一个接口对象的,我们可以通过配置让Moq模拟所有可以Mock的对象.

    我们新增如下代码

     public interface IDtoWrapper
        {
            MyDto Dto { get; set; }
            string GetString();
        }
    
        public interface IOutString
        {
            IDtoWrapper wrapper { get; set; }
    
        }
    

    比如我们要模拟一个IOutString对象,如果不使用默认的行为则里面的wrapper对象返回为Null,如果这样我们没法再继续操作了.

    我们可以对Moq的Default行为进行配置,让它对IDtoWrapper对象也进行Mock

    测试代码如下

           [Test]
            public void BehaviorConfig()
            {
                var moq = new Mock<IOutString>();
                moq.DefaultValue = DefaultValue.Mock;
                Assert.NotNull(moq.Object.wrapper);
            }
    

    以上测试会通过.这时候wrapper不再是null,我们便可以对其进行操作了.

    我们通过调试可以发现这时候不但IDtoWrapper不再是null,它里面的Dto属性也被赋值为一个new MyDto.是不是Mock框架可以模拟一个对象呢,实际上确实是可以,只不过是它模拟对象有很多限制,比如不能模拟不包含无参构造函数的对象,不能模拟不带virtual或者abstract的方法等.如果我们对模拟的对象的方法没有virual或者abstract修饰,这时候如果进行setup则会抛出异常.

    前面我们讲的如何通过配置使mock自动mock遇到到层级可Mock对象.这一节我们来看另一个问题.

    假如有这样一种场:要mock的接口里有一个Name属性,在业务层我们要根据这个Name决定进入switch的不同分支里面,但是回顾前面的章节,我们没有遇到这种情况,我们都是只是在mock对象建立时使用setup为要mock的对象的字段设置值.很多人可能会想,可以通过moq对象实体的Object属性把这个对象拿出来,然后改变它的值.我们来看看这样做可行不可行.

    我们有以下一个简单接口

      public interface ISt
        {
            string Name { get; set; }
            int Age { get; set; }
        }
    

    测试方法如下

           [Test]
            public void BehaviorConfig()
            {
                var moq = new Mock<ISt>();
                var obj = moq.Object;
                obj.Name = "baidu";
                Assert.NotNull(moq.Object.Name);
            }
    

    我们把moq的Object对象赋值给obj,然后通过obj改变Name值.我们断言moq.Object.Name的值不为null,不幸的是,测试没有通过.

    Avatar

    按我们理解obj和moq.Object应该是引用类型,所以obj值的改变会引起moq.object值的改变,然而实际情况却是我们一旦把moq.Objectm赋值给了obj,它们之间便脱离了关系.看来这样是行不通的.

    如何解决这个问题呢,其实moq实例对象里面有一个SetupProperty方法,我们可以通过它来显示指定哪些属性会被跟踪,如果属性被跟踪,则它的变化就会被记录下来,而不像上面.

            [Test]
            public void BehaviorConfig()
            {
                var moq = new Mock<ISt>();
                moq.SetupProperty(a => a.Name);
                var obj = moq.Object;
                obj.Name = "baidu";
                Assert.NotNull(moq.Object.Name);
            }
    

    我们多加了一行代码,测试便可以通过了.

    但是如果属性很多,这样一行一行几乎重复的代码挺烦的,moq实例里面还有一个SetupAllProperties方法,这样可以设置所有的属性都被跟踪.这样如果多条需要这个值,我们便不需要每次都mock它,而只需要给它重新赋值即可.

  • 相关阅读:
    CodeForces 288A Polo the Penguin and Strings (水题)
    CodeForces 289B Polo the Penguin and Matrix (数学,中位数)
    CodeForces 289A Polo the Penguin and Segments (水题)
    CodeForces 540C Ice Cave (BFS)
    网站后台模板
    雅图CAD
    mbps
    WCF学习-协议绑定
    数据库建表经验总结
    资源位置
  • 原文地址:https://www.cnblogs.com/tylerzhou/p/11416041.html
Copyright © 2011-2022 走看看