Jed*_*d I 5 c# unit-testing moq mocking
我是 MOQ 的新手,我对设置方法有点困惑。下面的示例显示了我需要测试的一种方法。被测方法返回两个日期的最新时间,因此我创建了两个 datetime 对象并将它们传递给我的函数。我感到困惑的部分是返回调用。这会忽略我的方法中的逻辑并返回我告诉它的内容。例如,如果我说返回(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);
}
Run Code Online (Sandbox Code Playgroud)
您以错误的方式使用 Moq。它旨在替代您的测试类所依赖的某些实现。例如,您正在测试一些使用数据库存储库的类:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
您需要测试该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]);
}
Run Code Online (Sandbox Code Playgroud)
SoMoq
允许您动态生成假类(非密封)或接口实现(在运行时),并使用它们将您的测试功能与其他一切分离。因此,如果 DB 结构中出现错误,您只会看到少数 DB 测试失败,并且如果您没有将代码与 Moq 解耦,那么与来自所有层的 100 个不同测试失败的情况相比,您可以轻松确定问题所在.