2015-04-12 37 views
0

我想测试一个特定的方法是否会产生预期的结果,但要做到这一点,我还需要在测试中操作输入。我是否应该在实际课程中重复代码

class ToTest { 
    public String produceResponse(String input) { 
    // .... 
    encryptedIds = encryptIds(input) 
    output = doStuff(input, encryptedIds) 
    } 

    public encryptIds(input) { 
    .... 
    } 
} 

在我的测试中,我需要检查produceResponse实际上是否产生预期的响应。 为了做到这一点,我必须加密输入中的ID。

我的问题是:我应该在测试中重写encryptIds(这样我就可以有更多的控制器)或者我应该从类本身调用encryptIds。

有没有更好的方法来解决这个问题?我不喜欢我的测试,我知道特定流程会发生什么。

回答

3

如果我理解正确,你想测试produceResponse()已知encryptedIds作为输入。

你可以做,没有重构的代码,但它很可能是一个好主意,重构它,所以这就是我要解释一下:

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到测试它是否会根据字符串输入生成正确的加密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() 
0
  1. 切勿将任何生产代码复制到单元测试中,因为它会在某个时间点过期。
  2. 如果这两种方法是公开的,他们是公共API的一部分,所以:

    • 你应该先单元测试encryptIds(String)方法
    • 然后单元测试produceResponse(String)方法的正确行为,将内部使用已经测试encryptIds(String)方法
  3. 如果encryptIds(String)不会是公共API的一部分:

    • 那么它是内部实现和辅助方法,是不是可以进行单元测试
    • produceResponse(String)然后用于加密的副作用负责:
      • 你仍然可以测试它,如果你将其标记包专用(无改性剂)
      • 你也可以改变encryptIds(String)实施仅用于测试目的
+0

如果encryptIds不是API的一部分,该怎么办? – user844541

+0

增加了更多描述 – Crazyjavahacking

0

是加密id的东西是不可或缺的东西是你的系统?就目前而言,这门课程需要一些输入并产生一些输出,并且就您的测试而言,这是重要的,不多也不少。

不执行加密的影响是什么?如果你的doStuff方法如果没有发生就会失败,那么它就是你的待测类的内部细节,我根本就不会关心它。如果这是绝对必须执行的步骤,那么我会重构代码以验证它绝对发生了,也许使用@ jb-nizet的模拟回答。

至于重复生产代码测试,@Crazyjavahacking说,你不应该这样做的一般情况,但我必须使用带有没有问题生产代码从测试 - 也许不是在单元级,但绝对是比我更高的系统,例如当测试写入数据库时​​,我将使用读取代码来验证它是否正确发生,但也将有独立测试来验证读取路径以及

相关问题