我有两个表,客户端和管理员,它们由表ClientAdministrators以多对多关系链接。
在真实的应用程序中,这工作正常,我可以获取客户端的管理员列表。我的问题在于尝试对从存储库中检索此服务的服务类进行单元测试。
我有一个实现我的存储库接口的FakeRepository类,我有几个内部的对象列表供服务类查询。
我的问题是我找不到让关系在假类中工作的方法,以便能够成功地查询这种多对多关系。
Dim clients = From c in _repository.GetAllClients _
Select New ClientBizObj With {.ID = c.ID, _
.ClientName = c.ClientName, _
.Admins = (From a in c.ClientAdministrators _
Select a.Administrator.UserName).ToList}
它告诉我c.ClientAdministrators是一个EntitySet(ClientAdministrator)。
如何在我的FakeRepository类中伪造这种关系,以便它停止抛出NullReferenceExceptions?
我不在乎是否不返回任何管理员,我只需要成功返回Client对象。
答案 0 :(得分:2)
这必须是Roy Osherove(TypeMock的首席架构师和本书作者“单元测试的艺术”)建议不要嘲笑数据库操作的原因之一。他建议这样的测试是relegated to the integration tests,并且实际的数据库应该参与这样的测试。
答案 1 :(得分:2)
在您的示例中,您专门尝试模拟数据访问层,而不是数据库操作本身。这在单元测试中非常合理,可以将逻辑与持久性问题隔离开来。
您描述的问题可以通过创建Clients类的模拟来解决。在此模拟中,您可以覆盖ClientAdministrators属性以返回空集合,但将其他所有内容委托给真实类。然后,您将需要您的FakeRepository类来返回您的模拟而不是真正的Clients类。
有几种模拟工具可以轻松实现。其中,最容易使用(和开源引导)之一是moq。使用moq,您应该可以模拟出所有数据访问层进行测试,因此您甚至无需构建自己的FakeRepository类。
答案 2 :(得分:1)
你可以使用Dev Magic Fake假冒数据库而不是Mock DB,换句话说你可以模拟UI, 通过执行以下操作:
[HttpPost]
public ActionResult Create(Client model)
{
var repository = new FakeRepository<Client>();
repository.Save(model)
有关更多信息,请参阅CodePlex上的DevMagicFake
由于
M.Radwan