【发布时间】:2011-02-10 13:35:16
【问题描述】:
我的服务层中有以下简单方法。我不确定如何从存储库开始模拟不同的链接部分?
public ICollection<GameFile> FindAllActiveGamesFiles()
{
return _gameFileRepository // <- this is an IRepository<GameFile>
.Find() // <-- returns an IQueryable<T> .. in this case, an IQueryable<GameFile>
.WhereIsActive() // <-- a simple Pipe/Filter; 'where x.IsActive'
.ToList();
}
我的偏好是使用起订量,但我很高兴看到其他的暗示.. 主要是因为我不是在追求确切的语法答案,而是在理论上的答案。 IE。你只需要模拟IRepository<GameFile> 并设置ToList() 方法.. 等等等等...
这就是我不明白我应该嘲笑的东西。
干杯:)
--- 更新:澄清我的问题
我要测试的是“FindAllActiveGamesFiles()”方法是否有效。因此,我相信我需要模拟 gameFileRepository (这是一个接口)。我不确定这是否是我在这个例子中唯一应该嘲笑的事情。
例如。
[TestMethod]
public void MyTest()
{
// Arrange.
Mock<IRepository<GameFile>> mockRepository = new Mock<IRepository<GameFile>>();
mockRepository.Setup(....).MoreStuffToDo(...); // <-- that's what i'm unsure about.
IGameFileService = new GameFileService(mockRepository, fakeLoggingService);
// Act.
var gameFiles = gameFileService.FindAllActiveGamesFiles();
// Asserts.
Assert.IsNotNull(gameFiles);
CollectionAssert.AllItemsAreNotNull(gameFiles.ToArray());
// .. and more asserts ///
// What about expectations? eg. that ToList() was entered/called?
}
【问题讨论】:
-
我很困惑!您不模拟方法,而是模拟类型/接口。那么您的意思是如何为单元测试设定期望值?
-
听起来你想通过模拟各种调用来单元测试这个方法。我的看法是,上面的例子太简单了,无法测试。如果您的测试代码最终比被测代码更复杂,那么您就是在浪费时间。用它来直观地验证方法并继续前进。
-
如果你有类似的,更复杂的链式方法来模拟,你基本上需要为每个返回的对象创建一个模拟,只有一个期望(如果链中的每个方法返回一个不同的对象,就像你在这里)。它可以是一个真正的 PITA 来设置和验证,因此只有在传递给各个方法调用的参数很复杂并且需要测试时才会得到回报。不要浪费时间测试
userName参数是否已传递给byUserName()。 -
@David Harkness & @Aliostad - 我更新了 OP 以进一步解释我的问题。我知道上面的场景可能是悔恨的,但它仍然是一个真实的例子,我觉得我仍然需要测试这个方法。
-
您到底在 FindAllActiveGamesFiles() 内部测试什么?它只是调用 _gameFileRepository.Find().WhereIsActive().ToList();您是否已经在测试这些方法中的每一个?如果是这样,那么你就完成了。 ;)
标签: .net unit-testing testing mocking