我正在为我的grails应用程序编写单元测试,并且我意识到我并不知道确定对象是否是正确对象的正确方法。
例如,鉴于此测试:
void testExampleTest() {
mockSession.person = new Person(firstName:'John', lastName:'Doe', middleInitial:'E')
def model = controller.testMethod()
...assertions...
}
和
def testMethod = {
Person currPerson = session.getAttribute("person")
render(view:'view',model:[person:currPerson]
}
我应该如何确保我添加到会话中的人物对象在模型中正确传递?是否足以使用
assertEquals( person,model['person'] )
或者因为我自己将对象注入会话中使用
更有意义assertEquals( person.firstName, model['person'].firstName )
assertEquals( person.lastName, model['person'].lastName )
assertequals( person.middleName, model['person'].middleName )
在我看来,只要对象具有正确定义的equals方法,第一种方法就足够了,但我只想看看传统方法是什么。
由于
答案 0 :(得分:4)
每次测试都需要重复逐个属性的比较 - 所以这是一个很好的旧代码重复,a test smell described in XUnitPatterns。最好有一个合适的equals()
。
当然,您可以在运行时添加实用程序方法personEquals()
甚至覆盖Person.equals()
。对于模拟课程,您可能必须这样做。我个人坚持使用更短的代码,如果可能的话只需要assertEquals()
。
答案 1 :(得分:2)
很有趣,我和一位同事今天也有过类似的讨论。我们的结论是
逐个属性比较费力的一个优点是它报告了一个特定的差异,而不仅仅是“不,它们不等于”,这可能很方便。
此外,我们无法控制某些类,其中一些类缺少等号方法。
我们打算调查是否可以使用反射来实现比较器,从而消除一些单调乏味。
答案 2 :(得分:2)
我发现通过财产做财产更加可靠,并且可以让你对比较某些事情有一点点精细控制,不利的是,设置和维护的工作要多一些
答案 3 :(得分:1)
如果正确定义了等号,那你就是对的。问题是,如果正确定义了equals(意味着它的行为与你期望的一样),你可能必须先进行单元测试。
如果为Person类创建一个模型,这可能会变得更加困难。在这种情况下,您不关心equals是否正常工作,因为您只想检查是否正确设置/访问了某些属性。这就是为什么我更喜欢在可能和必要时检查原始值。我发现它使测试更具描述性(虽然它可能变得非常冗长)。
答案 4 :(得分:1)
在这个特定的实例中,测试单个属性只是一种识别对象特定实例的方法,它会覆盖测试的含义。您特别关注并且应断言的是model['person']
与您最初作为person
输入的内容完全相同的对象:
assertSame(person, model['person'])
或者使用Hamcrest,它可以提供更具表现力的断言:
assertThat(model['person'], sameInstance(person))
答案 5 :(得分:0)
正如您所写,如果测试数据具有正确的equals方法,您可以使用它。这里的“正确”意味着它会测试您想要测试的属性。
我经常使用仅比较其ID属性的数据库实体。使用这些对象,我需要分别测试每个属性以查看它们是否相等。我写了一个小助手,允许我为许多属性编写一个断言,如:
assertEqualProperties(person, model['person'], "firstName", "lastName", "middleName");
这个帮助器方法使用反射来访问属性(不是直接,我调用commons-beans库)。在Groovy中,肯定有一种语法不需要显式反射。该方法将第一个不相等的属性报告为测试失败。
答案 6 :(得分:0)
在Grails中,每个对象都是可序列化的,因此您可以使用XML序列化比较两者:
public void compareXML(Object a, Object b)
ByteArrayOutputStream aBaos = new ByteArrayOutputStream();
XMLEncoder aEncoder = new XMLEncoder(aBaos);
aEncoder.writeObject(a);
aEncoder.close();
String xmlA = baos.toString();
ByteArrayOutputStream bBaos = new ByteArrayOutputStream();
XMLEncoder bEncoder = new XMLEncoder(bBaos);
bEncoder.writeObject(b);
bEncoder.close();
String xmlB = bBaos.toString();
assertEquals(xmlA, xmlB);
}
如果您在eclipse中工作,您将获得两个显示所有差异的XML字符串的文本比较。
答案 7 :(得分:0)
我使用assertSame()
。逐字段比较比必要的工作更多 - 你模拟了数据,所以只是断言模拟的值被正确返回。