这听起来比我的意思更模糊,但是当在类中测试方法时,正确的过程是什么。
e.g。客户类将设置密码的md5哈希值保存到数据库,而不是实际密码。客户类中的私有方法可以使用md5哈希进行保存。
public class Customer() {
public void setPassword(String password){
this.password = hashPassword(password);
}
private String hashPassword(String password){
..do stuff..
}
.. other methods ..
}
现在这只是一个例子,我不想知道如何计算md5哈希等。这是关于测试的。这是我能想到的选择:
答案 0 :(得分:4)
您应该选择第二个选项,即预先计算一个值或一系列值,然后使用它们进行测试。除了增加代码重复量之外,使用相同方法的副本测试方法没有任何意义。
答案 1 :(得分:1)
这样做
我手动计算特定密码(myPassword)的结果,并将其存储为常量。在测试中将密码设置为myPassword后,我会将常量与结果进行比较。
通过将实现与相同的实现结果进行比较,测试实现是没有意义的。
答案 2 :(得分:1)
我不会使用相同的算法,因为您可能会在两个实现中实现相同的错误。我不会手动计算,因为这种手动计算可能是错误的。相反,我会使用一些参考输入并检查算法的输出是否与参考输出相同。见the following page:
MD5 test suite:
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
d174ab98d277d9f5a5611c2c9f419d9f
MD5 ("123456789012345678901234567890123456789012345678901234567890123456
78901234567890") = 57edf4a22be3c955ac49da2e2107b67a
现在,如果您信任MD5的实现,并且只想检查是否已调用消化器,则可以注入模拟MD5消化器,并在设置密码时检查是否调用了模拟消化器。
答案 3 :(得分:1)
我肯定会采取第二种方法。您想要的最后一件事是让您的测试代码在“被测单元”中复制功能。
setPassword
的测试
这里的奖励是您没有测试hashPassword
方法。您正在验证密码是否已正确哈希。您的测试代码甚至不应该知道或关心私有方法是否存在。我会质疑你是否应该测试密码是否被哈希,因为它实际上是Customer
类的实现秘密,但你可能有充分的理由进行测试。
答案 4 :(得分:0)
也有第3种选择。
您可以使用JunitAddons库,它允许您使用反射测试私有方法,但它会为您隐藏反射的复杂性。
示例:通过方法setValue()将对象obj的值设置为100:
PrivateAccessor.invoke( obj, "setValue", new Class[]{int.class}, new Object[]{
new Integer( 100 )} );
如果对象具有基本类型,则该方法返回的值将自动包装在对象中。
答案 5 :(得分:0)
从您的选项编号2我将使用ie openssl计算并存储它,以便以后比较:)
答案 6 :(得分:0)
我假设您要测试私有方法,因为它包含一些重要的逻辑。也许最好的方法是将该方法的主体移动到某个外层?
您的代码片段就是一个很好的例子 - 计算MD5应该在Customer类之外完成 - 这不是Customer的责任。
private String hashPassword(String password) {
this.hash = PasswordHasher.hash(password)
}
以后public(or default/protected) String PasswordHasher#hash(String)
很容易被测试