再说模拟测试
模拟一个方法
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