为了使一个具体的例子,我有PromoCode
聚合根是由PromoCodeUsage
实体,仅由AR控制,以便在AR一些方法只是委托给该实体,如:如何测试将其调用委托给AR实体的Aggregate Root的方法?
public function useFor(Order $order): void
{
$this->promoCodeUsage->useFor($order);
}
有些他们被部分下放,如:
public function applyFor(Order $order): void
{
if (!$this->published) {
throw new NotPublishedPromoCodeCanNotBeApplied();
}
$this->promoCodeUsage->applyFor($order);
}
我的测试套件完全覆盖,包括PromoCodeUsage
功能的所有PromoCode
行为,因为在那个迭代没有PromoCodeUsage
和所有的逻辑在混合。然后我重构了一些逻辑到PromoCodeUsage
。这个测试套件为PromoCode
进行了很多测试,我很高兴我也可以分解它(但它在分割实体后仍然运行良好)。所以我创建了另一个测试套件(PromoCodeUsageTest
),我从PromoCode移动了部分测试。
但是PromoCodeUsageTest
s正在测试PromoCodeUsage
实体通过PromoCode
的行为,就像它在拆分前的原始测试中一样。他们不直接触摸PromoCodeUsage
。现在我有PromoCodeTest
套房设有: 而PromoCodeUsageTest套房设有:
但它是有点怪异,即1)PromoCodeTest
我省略了一些测试(在别处)和2)PromoCodeUsageTest
我其实不触摸PromoCodeUsage
实体。 3)我使用Roy Osherove的模板进行测试命名,我不知道应该在测试名称中使用什么方法名称 - 从PromoCode或PromoCodeUsage?在我的情况下,他们是相同的,但他们可能会有所不同,这个想法有味道
如果我重写PromoCodeUsageTest
s到直接测试PromoCodeUsage
实体,我结束了在PromoCode
一些未覆盖的方法(即只是委托给PromoCodeUsage
)。所以这让我回到我的方法来测试PromoCodeUsage
到PromoCode
AR。
Bob叔叔(和其他人)说,测试行为而不是API是很好的做法。我的方法是否符合?
因为我的方法感觉有些异味,对吗?如何做得更好?
http://stackoverflow.com/a/153565/54734 – VoiceOfUnreason
*“在PromoCodeUsageTest我实际上没有触及PromoCodeUsage实体”* - 甚至在断言? – guillaume31
@ guillaume31不,我通过AggregateRoot断言。而且,我并没有太多断言,我宁愿没有断言知道,当我已经测试了引发预期异常的所有情况时,可以在不抛出异常/错误的情况下执行该操作。因为我发现,我需要在我的实体上拥有getter才能执行这些断言,我认为这是不好的,不仅仅是因为只有测试方法,而是因为我会测试API而不是行为。 – Tom