你的位置:首页 > ASP.net教程

[ASP.net教程]再说模拟测试


模拟一个方法

Controller:

namespace WebApplication1.Controllers

{

    public class TestController : Controller

    {

        public TestController(IService service)

        {

            this.Service = service;

        }

        public IService Service { get; set; }

        // GET: Test

        public virtual ActionResult Index()

        {

            var result = this.Service.Foo();

            ViewBag.res = result;

            return View();

        }

    }

}

测试代码:

namespace MyTest

{

    public class Class1

    {

        [Fact]

        public void IndexTest()

        {

            var mock = new Mock<IService>();

            mock.Setup(s => s.Foo()).Returns("我是模拟的");

            TestController controller = new TestController(mock.Object);

            ViewResult result = controller.Index() as ViewResult;

            Assert.Equal("我是模拟的", result.ViewBag.res);

        }

    }

}

利用Mock实现IService里指定的方法,我们实现了Foo方法。再调用TestController里Index方法时,里的Foo方法其实是我用Mock模拟的一个方法并不是真实项目里的方法。

模拟一个没有返回值得方法

Controller:

namespace WebApplication1.Controllers

{

    public class TestController : Controller

    {

        public TestController(IService service)

        {

            this.Service = service;

        }

        public IService Service { get; set; }

        // GET: Test

        public ActionResult Index()

        {

            this.Service.Foo();

            return View();

        }

    }

}

测试代码

namespace MyTest

{

    public class Class1

    {

        [Fact]

        public void IndexTest()

        {

            var mock = new Mock<IService>();

            mock.Setup(s => s.Foo());

            TestController controller = new TestController(mock.Object);

            ViewResult result = controller.Index() as ViewResult;

            mock.Verify(s => s.Foo());

            Assert.NotNull(result);

        }

    }

}

当模拟的方法没有返回值的时候我们要确定方式是否执行了,可以使用mock.Verify();来判断方法时候被调用,使用方法如上。也可以在设置模拟方法是指定是否验证被调用,例如:

利用Verifiable()

 mock.Setup(s => s.Foo()).Verifiable();

mock.Verify();

Ps:VerifyAll()是验证所有的方法,不需要指定

参数验证

利用It.Is<>()对参数做一个验证,例如

It.Is<int>(i => i == 1),参数是1的int类型

mock.VerifyAll();

属性

给属性设置默认值:

mock.Setup(s => s.Lala).Returns("12390")

mock.SetupProperty(s => s.Lala, "12398");

验证:

mock.SetupSet(s => s.Lala = "1232");//设置期望值

mock.VerifyAll();//验证Controller里的赋值是否与期望值一致

Action<IService> action = i => { i.Lala = "1232"; };

mock.VerifySet(action);

Ps:验证是常量值也可以使用It类里的方法代替,例如

It.Is<string>(p => p == "33")

验证是否被调用:

mock.VerifyGet(s => s.Lala);

mock.Setup(s => s.Lala).Verifiable();

mock.Verify();

mock.Setup(s => s.Lala)

mock.VerifyAll();

跟踪属性值:

mock.SetupProperty(s => s.Lala, "00");//这样设置属性就可以被跟踪,就可以被修改

var obj = mock.Object;

obj.Lala = "90";//修改跟踪的属性

Ps:mock.Setup(s => s.Lala).Returns("12390"),设置属性不会被跟踪

模拟受保护的方法:

var mock = new Mock<Bar>();

mock.Protected().Setup<string>("Ox").Returns("321");

var res = mock.Object;

直接用mock的Setup,是没法模拟protected方法的,mock.Protected()就是为了解决这个问题的。

Ps:引用命名空间using Moq.Protected;

测试私有方法:

Bar bar = new Bar();

var barPrivate = new PrivateObject(bar);

var result = barPrivate.Invoke("Pp");

Ps:引用Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll,路径是C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\PublicAssemblies\(根据vs版本不同有所不同)下,需要手工添加引用

参考文章:

http://www.cnblogs.com/darrenji/p/3869602.html#a

http://www.cnblogs.com/haogj/archive/2011/07/22/2113496.html

http://www.cnblogs.com/gossip/archive/2012/05/16/2503477.html