2

我有两个表,Clients 和 Administrators,它们通过表 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 对象。

4

3 回答 3

2

这一定是Roy Osherove(TypeMock 的首席架构师和《单元测试的艺术》一书的作者)建议不要模拟数据库操作的原因之一。他建议将此类测试归结为集成测试,并且实际数据库应参与此类测试。

于 2009-08-06T20:25:19.580 回答
2

在您的示例中,您专门尝试模拟数据访问层,而不是数据库操作本身。这在单元测试中是完全合法的,可以将您的逻辑与持久性问题隔离开来。

您描述的问题可以通过创建客户类的模拟来解决。在这个模拟中,您可以覆盖 ClientAdministrators 属性以返回一个空集合,同时将其他所有内容委托给真正的类。然后,您将需要您的 FakeRepository 类来返回您的模拟,而不是真正的 Clients 类。

存在几种模拟工具可以使这变得容易。其中,最容易使用(并且是开源启动)之一是moq。使用 moq,您应该能够模拟出所有数据访问层以进行测试,因此您甚至不需要构建自己的 FakeRepository 类。

于 2009-08-16T17:36:38.237 回答
1

您可以使用 Dev Magic Fake 来伪造数据库而不是模拟数据库,换句话说,您可以通过执行以下操作来模拟 UI:

[HttpPost]
public ActionResult Create(Client model)
{
   var repository = new FakeRepository<Client>();
   repository.Save(model)

有关更多信息,请参阅 CodePlex 上的 DevMagicFake

devmagicfake.codeplex.com

谢谢

拉德万

于 2011-09-06T12:17:09.867 回答