.net测试篇之Moq行为配置

系列目录html

咱们前面说过.Moq在建立模拟对象的时候,简单对象赋值默认值,引用对象赋值为null,可是有些时候接口里面还包含另外一个接口对象,咱们知道Moq是能够模拟一个接口对象的,咱们能够经过配置让Moq模拟全部能够Mock的对象.app

咱们新增以下代码框架

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,咱们即可以对其进行操做了.code

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

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

假若有这样一种场:要mock的接口里有一个Name属性,在业务层咱们要根据这个Name决定进入switch的不一样分支里面,可是回顾前面的章节,咱们没有遇到这种状况,咱们都是只是在mock对象创建时使用setup为要mock的对象的字段设置值.不少人可能会想,能够经过moq对象实体的Object属性把这个对象拿出来,而后改变它的值.咱们来看看这样作可行不可行.blog

咱们有如下一个简单接口

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它,而只须要给它从新赋值便可.