我是MOQ的新手,我对安装方法有点困惑。下面的示例显示了我需要测试的一种方法。测试中的方法返回两个日期的最新时间,因此我创建了两个日期时间对象并将它们传递给我的函数。我感到困惑的部分是回复电话。这会忽略我方法中的逻辑并返回我告诉它的内容。例如,如果我说返回(date2),则无论逻辑如何,断言都会通过。我做错了吗?
public virtual DateTime LatestTime(DateTime t1, DateTime t2)
{
if (t1.CompareTo(t2) > 0)
return t1;
return t2;
}
[Test]
[Category("Catalogue service")]
public void TestLatestTimeReturnsCorrectResult()
{
//Arrange
DateTime date1 = new DateTime(2014, 07, 25, 13, 30, 01);
DateTime date2 = new DateTime(2014, 07, 25, 13, 30, 00);
MockCatalogueService.Setup(x => x.LatestTime(date1, date2)).Returns(date2);
//Act
DateTime retDate = MockCatalogueService.Object.LatestTime(date1, date2);
//Assert
Assert.That(retDate == date2);
}
答案 0 :(得分:0)
你以错误的方式使用Moq。它旨在替换您测试的类所依赖的某些实现。例如,您正在测试一些使用DB存储库的类:
public class MyService
{
private IMyDbRepository _repos;
public MyService(IMyDbRepository dbRepos)
{
_repos = dbRepos;
}
public string[] GetClientNames()
{
return _repos.GetAllClients().Where(c=>!c.IsDisabled).OrderBy(c=>c.Name).ToArray();
}
}
您需要测试GetClientNames()
方法。但是,除非你有IMyDbRepository
个实例,否则你不能。创建和填充数据库只是为了测试排序和过滤客户端的方法,这太复杂和错误。
出路是使用Moq
:
[Test]
public void TestGetAllClientsDoesNotReturnDisabledUsers()
{
var dbReposMock = new Mock<IMyDbRepository>();
dbReposMock.Setup(r=>r.GetAllClients()).Returns(
new []{ new Client { Name="AAA", IsDisabled=true },
new Client { Name="BBB", IsDisabled=false } });
var myTestingService = new MyService(dbReposMock.Object);//You pass here the autogenerated object which follows the described primitive behavior without requiring DB at all.
var clientNames = myTestingService.GetClientNames();
Assert.AreEqual(1, clientNames.Length);
Assert.AreEqual("BBB", clientNames[0]);
}
因此Moq
允许您动态生成假类(非密封)或接口实现(在运行时),然后使用它来将您的测试功能与其他所有内容分离。因此,如果数据库结构中出现错误,您会发现只有少数数据库测试失败并且可以轻松识别问题是什么,如果您没有将代码与Moq解耦,则所有层中的100个不同测试失败的情况。