2011-09-25 72 views
3

我是新来的单元测试& TDD和阅读一些文章,我决定在我的小项目开始后TDD。这是一个简单的剧院票预订,它也使用NHibernate & Repository模式。我决定先为我的数据模型写一些测试,所以我开始对实体进行简单的CRUD操作。我面临的第一个问题是具有多对一关系的实体。例如我有有许多-to-one关联到主任实体(每个展会都有一个董事)一显示实体,因此对于测试Show.Create方法我不得不创建一个主任实体来分配他首先显示。单元测试的数据模型:相关实体

由于单元测试极力劝阻编写相关的测试,我怎么能绕过这个问题未做任何依赖这些相关实体?

回答

3

我觉得将TDD当作一个如何使用某些东西的例子很有帮助,为什么这个行为很有趣。

因此,例如,在你的应用程序,你可能有这样的行为:

它的创建当A显示与导演有关。

然而,这不是很有趣。为什么这很有价值?它在哪里使用?如果您可以展示某些重要的行为方面,那更有意思。

一个节目的声誉开始了与它的导演的声誉。

然后,您可以编写此行为的例子:

Given a director with a reputation of 75% 
When he creates a new show 
Then the show should start with a reputation of 75%. 

这将是更有趣的行为。我们实际上可以创建一个具有这种声誉的节目,而不使用Hibernate。我有时候会把这样的例子作为测试中的评论。 (我用这个作为例子,因为我不知道为什么用导演创建节目对你来说很重要!)

对于像NHibernate这样的东西,要么使用覆盖整个应用程序的全栈场景,要么集成测试只需通过与其导演构建一个节目来检查映射,或者手动检查应用程序的工作情况。如果你正确地使用NHibernate,你可以假设NHibernate将继续工作,所以与你将要改变的代码相比,你需要更少的测试。

我的经验是,它是确定以创建真正的域对象(显示,导演等),而不是嘲笑他们。但是,如果您有任何复杂的计算 - 例如,计算一次Show一旦开始几个晚上的声望可能会很复杂 - 那么您可以注入一个模拟来帮助解决这个问题,并且您的行为也会相应改变:

A show uses the reputation rules for its reputation 

// Given the reputation rules 
(mock out the reputation) 

// When a show is created with a director 
(create the show) 

// And it's shown for 3 nights with varying reviews 
(associate the reviews with the show) 

// Then it should use the rules to calculate its reputation 
(verify that when you get the reputation, the show asks the mock for help). 

希望这可以让你知道它在哪里可能是有用的嘲笑,以及它可能不需要。这越练习越自然。

+0

谢谢你的有用答案。 完全测试实体的目的是检查映射文件的健康性等,但在阅读您的解释之后,我认为它应该在集成测试中进行分类,并且不能进行单元测试。我对吗 ? – sos00

+0

绝对 - 做一个集成测试。映射文件的行为只有在与真实数据库一起使用时才有价值。 – Lunivore

0

只需创建一个IDirector接口,您将放入显示实体的构造函数中。这样,您可以在分配给节目之前创建导演的模型(测试)实现。只需使用一些虚拟数据或我们的Rhino Mocks自己实现IDirector接口。一个例子见http://haacked.com/archive/2006/06/23/usingrhinomockstounittesteventsoninterfaces.aspx

+0

谢谢,我熟悉存根和模拟对象,但在这种情况下,我想测试一个真正的插入测试数据库,所以为了添加新的显示到显示表我需要一个真正的导演记录在那里。我不知道也许我错了,对真正的数据库进行测试并不是单元测试的重点? – sos00

+0

单元测试的挑战是正确隔离被测单元。因此,在测试Show时,您不必关心Director。我不确定如何使用NHibernate生成的实体来实现该功能,但可以想象,您可以创建一个仅用于满足Show的构造函数的Director模型实体。 – kroonwijk