以下是Mockito单元测试框架的引用:
Don’t mock value objects
Why one would even want to do that?
Because instantiating the object is too painful !? => not a valid
reason. If it’s too difficult to create new fixtures, it is a sign the
code may need some serious refactoring. An alternative is to create
builders for your value objects — there are tools for that, including
IDE plugins, Lombok, and others. One can also create meaningful
factory methods in the test classpath.
here的另一个引用:
There isn’t much point in writing mocks for simple value objects
(which should be immutable anyway), just create an instance and use
it. It’s not worth creating an interface / implementation pair to control which time values are returned, just create instances with the appropriate values and use them. There are a couple of heuristics for when a class is not worth mocking. First, it has only accessors or simple methods that act on values it holds, it doesn’t have any interesting behaviour. Second, you can’t think of a meaningful name for the class other than VideoImpl or some such vague term.
这似乎是哑巴值对象只保留值的有效原因,但是当你有一个引用实体和其他值对象的ValueObject时,事情变得更加复杂.
假设我有Person和Pet对象,它们是实体和Relationship(所有者,医生等),它们是两个人之间的ValueObject,并且具有RelationshipType,它也是一个Value Object.所以,关系基本上是:
class Relationship {
private Person person;
private Pet pet;
private RelationshipType type;
}
现在,假设我有一个带有isOwnerRelationship,isDoctorRelationship等谓词的类.基本上谓词就像
relationship -> relationship.isOwner(); //delegates to relationshipType.isOwner()
现在,我想测试谓词,我有两个选择:
模拟关系
public void testIsOwner() {
Relationship rel = mock(Relationship.class);
when(rel.isOwner()).thenReturn(true);
assertTrue(RelationshipPredicates.isOwner(rel));
}
不要嘲笑关系
public void testIsOwner() {
Person person = PersonBuilder.newPerson();
Pet pet = PetBuilder.newDogPet();
RelationshipType type = RelationshipTypes.ownerType();
Relationship rel = new Relationship(person, pet, type);
assertTrue(RelationshipPredicates.isOwner(rel));
}
当然,这个例子已经过度简化,因为对于一个人来说,你可能需要提供地址,对于Pet你可能必须提供BreedType,无论如何,即你可能需要提供的实体和价值对象的传递图可能非常庞大.当然,您可以模拟实体,但假设您在关系中有更多ValueObjects的ValueObjects.即使你有花哨的构建器,你也必须提供原始ValueObject的每一部分,即使单元测试只测试它的单个方面.
在谓词测试中,如果谓词关心调用对象的一个特定方法或它们的组合,我为什么要关心完整的对象构造?
或者是这样的价值对象不能算是一个简单的规则并不适用?
解决方法:
UnitTests应测试单个单元.因此,如果您的ValueObject足够简单,那么它不应该影响SUT(被测试对象)的测试.但是,如果ValueObject具有复杂的行为,那么您应该模拟它.这简化了测试并将测试隔离到仅SUT.
标签:java,unit-testing,mocking,mockito,domain-driven-design
来源: https://codeday.me/bug/20190701/1348419.html