我想测试一个特定方法产生预期结果,但为此我还需要操作测试中的输入。
class ToTest {
public String produceResponse(String input) {
// ....
encryptedIds = encryptIds(input)
output = doStuff(input, encryptedIds)
}
public encryptIds(input) {
....
}
}
在我的测试中,我需要检查produceResponse是否实际产生了预期的响应。 为了做到这一点,我必须加密输入中的ID。
我的问题是:我应该在测试中重写encryptIds(以便我在结果上有更多的控制器),还是应该从类本身调用encryptIds。
有没有更好的方法来解决这个问题?在我的测试中我不喜欢这样,我知道具体流程中会发生什么。
答案 0 :(得分:3)
如果我理解正确,您希望使用已知的encryptedIds作为输入来测试produceResponse()
。
你可以在不重构代码的情况下做到这一点,但重构它可能是一个好主意,所以这就是我要解释的内容:
class ToTest {
private IdEncryptor encryptor;
public ToTest(IdEncryptor encryptor) {
this.encryptor = encryptor;
}
public String produceResponse(String input) {
String[] encryptedIds = encryptor.encryptIds(input);
return doStuff(input, encryptedIds);
}
}
现在,您可以对IdEncryptor进行单元测试,以测试它是否根据String输入生成正确的加密ID。
要测试ToTest类,您可以模拟IdEncryptor,这样无论它接收什么输入,它都会产生您想要的encryptedIds。例如,使用mockito:
IdEncryptor mockEncryptor = mock(IdEncryptor.class);
when(mockEncryptor.encryptIds(any(String.class)).thenReturn(new String[] {"a", "b"});
ToTest toTest = new ToTest(mockEncryptor);
String response = toTest.produceResponse("input");
// expect that the response is what you expect given "a", "b" as input of doStuff()
答案 1 :(得分:0)
如果两种方法都是公开的,则它们是公共API的一部分,所以:
encryptIds(String)
方法produceResponse(String)
方法进行单元测试,该方法将在内部使用已经过测试的encryptIds(String)
方法如果encryptIds(String)
不属于公共API:
produceResponse(String)
负责加密作为副作用:
encryptIds(String)
的实施答案 2 :(得分:0)
加密id是你系统不可或缺的东西吗?目前这个类需要一些输入并产生一些输出,就你的测试而言,这是重要的,不多也不少。
不执行加密有什么影响?如果你的doStuff
方法如果没有发生就会失败,那么它就是你的被测试阶段的内部细节,我根本不会让测试关心它。如果这是一个绝对必须执行的步骤,那么我将重构代码以验证它绝对已经发生,也许使用模拟作为@ jb-nizet回答。
至于在测试中复制生产代码的一般情况,正如@Crazyjavahacking所说,你不应该这样做,但我没有问题使用生产代码来测试 - 也许不是在一个单元水平,但绝对是我去的系统越高,例如当测试写入数据库时,我将使用读取代码来验证它是否正确发生,但也将进行独立测试以验证读取路径