1

这听起来比我的意思更模糊,但是在测试类中的方法时,正确的过程是什么。

例如,客户类将设置密码的 md5 散列保存到数据库,而不是实际密码。客户类中的私有方法计算出用于保存的 md5 哈希。

public class Customer() {

public void setPassword(String password){
  this.password = hashPassword(password);
}

private String hashPassword(String password){
  ..do stuff..
}

.. other methods ..

}

现在这只是一个例子,我不想知道如何计算 md5 哈希等。这是关于测试的。这是我能想到的选择:

  • 我在测试类中创建了一个与 hashPassword 相同的方法,然后比较结果。
  • 我手动计算特定密码 (myPassword) 的结果并将其存储为常量。在测试中将密码设置为 myPassword 后,我会将常量与结果进行比较。
4

7 回答 7

4

您应该采用第二个选项,即预先计算一个值或一系列值,并用它们进行测试。使用相同方法的副本测试方法除了增加代码重复量之外没有其他目的。

于 2012-11-25T13:25:44.293 回答
1

做这个

我手动计算特定密码 (myPassword) 的结果并将其存储为常量。在测试中将密码设置为 myPassword 后,我会将常量与结果进行比较。

通过将实现与相同实现的结果进行比较来测试实现是没有意义的。

于 2012-11-25T13:26:22.453 回答
1

我不会使用相同的算法,因为您可能会在两个实现中实现相同的错误。我不会手动计算,因为这种手动计算可能是错误的。相反,我会使用一些参考输入并检查您的算法的输出是否与参考输出相同。请参阅以下页面

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 摘要器,并在设置密码时检查模拟摘要器是否被调用。

于 2012-11-25T13:30:23.973 回答
1

我肯定会采取第二种方法。您想要做的最后一件事是让您的测试代码在“被测单元”中复制功能。

  1. 存储已知纯文本和散列结果的列表。
  2. setPassword添加一个使用纯文本调用的测试
  3. 添加一种方法来“检查”散列值 - 如果您要添加它以进行测试,则使这个包可见

这里的好处是您没有测试该hashPassword方法。您正在验证密码是否正确散列。您的测试代码甚至不应该知道或关心私有方法是否存在。我会质疑您是否应该测试密码是否经过哈希处理,因为它实际上是Customer该类的实现秘密,但您可能有充分的理由进行测试。

于 2012-11-25T13:32:48.300 回答
0

还有第三种选择。

您可以使用JunitAddons库,它允许您使用反射测试私有方法,但它为您隐藏了反射的复杂性。

示例:通过 setValue() 方法将对象 obj 的值设置为 100:

PrivateAccessor.invoke( obj, "setValue", new Class[]{int.class}, new Object[]{
    new Integer( 100 )} );

如果该方法返回的值具有原始类型,则该方法返回的值会自动包装在对象中。

于 2012-11-25T13:24:24.367 回答
0

从您的选项选项 2 我将使用 ie openssl 计算它并存储它,以供以后比较:)

于 2012-11-25T13:25:59.463 回答
0

我假设您想测试私有方法,因为它包含一些重要的逻辑。也许最好的方法是将该方法的主体移动到某个外部类?

您的代码片段是一个很好的例子 - 计算 MD5 应该在客户类之外完成 - 这不是客户的责任。

private String hashPassword(String password) {
    this.hash = PasswordHasher.hash(password)
}

后来public(or default/protected) String PasswordHasher#hash(String)很容易被测试

于 2012-11-25T13:33:03.230 回答