我正在尝试测试一种方法的行为以生成带有一些参数的URL。该方法利用了辅助方法,而辅助方法又使用了new Random().nextDouble()
。
private static String generateChecksum() {
return "s" + new Double(Math.floor(Instant.now().getEpochSecond() / 10800000)).longValue() % 10 +
new Double(Math.floor(10000000000000L * new Random().nextDouble())).longValue();
}
我对此特定测试的目标是确保方法的输出与我期望的相符。我的问题是我无法预测Random.nextDouble()
的结果。
我读到您可以模拟结果,并且我认为覆盖该方法的每个实例。我发现自己不能I shouldn't做那件事,但是我应该重新编写代码以适合我的测试。
如何重写它?我是否将校验和与参数一起传递到预先生成的方法中,所以我的流程来自:
1. Main()
2. generateUrl(params)
2a. generateChecksum() // for use in generateUrl
3. return URL
到
1. Main()
2. generateChecksum()
3. generateUrl(params, checksum)
4. return URL
还是我错过了什么?谢谢!
答案 0 :(得分:1)
为了使此类代码可测试,您有两件事很重要:
换句话说:您可以控制时间和生产代码将看到的随机数!
或者,将整个计算简单地委托到可以轻松模拟的东西中,例如:
public class CheckSumGenerator {
public String generate(...) { ...
现在,您可以轻松模拟该类,并使其返回您想要返回的任何内容。不用考虑时钟或随机数。
但是请记住:设置种子仍然是一个好主意,理想情况下,您可能希望使用 secure 随机数作为种子。
答案 1 :(得分:1)
最简单的解决方案是在您的方法中添加一个包含该随机数的新参数:
private static String generateChecksum(double r) {
return "s" + new Double(Math.floor(Instant.now().getEpochSecond() / 10800000)).longValue() % 10 +
new Double(Math.floor(10000000000000L * r)).longValue();
}
static String generateUrl(double r) {
// call generateChecksum(r)
}
public static String generateUrl() {
// trivial
return generateUrl(new Random().nextDouble());
}
现在,您可以轻松测试generateUrl(double r)
方法。您不需要测试generateUrl()
方法,因为它很简单。
答案 2 :(得分:0)
如果无法提前知道结果,则无法进行测试。
您需要注入随机性源作为依存关系,以便可以在测试中提供常量。
public class MyClass {
private final Supplier<Double> randomNumberGenerator;
public MyClass(Supplier<Double> randomNumberGenerator) {
this.randomNumberGenerator = randomNumberGenerator;
}
private String generateChecksum() {
//... randomNumberGenerator.get();
}
}
在您的应用程序代码中,像这样创建对象:
new MyClass(() -> new Random().nextDouble());
在您的测试中,如下所示创建它:
new MyClass(() -> 10.0);
您可以使用时间戳记执行相同的操作。 Supplier<Instant>
,Instant::now
,() -> Instant.ofEpochSecond(123456)
答案 3 :(得分:0)
虽然您确实不知道使用随机组件的方法的 exact 输出是正确的,但我认为没有必要测试任何精确的输出,而是测试正确的输出输出的格式,即验证输出是 a 有效URL,而不是消除随机性的特定实例。
当然,输出可能会偶然通过此检查,但是选择特定的种子实际上会遇到相同的问题。