Java 我应该在测试中在实际类中重复代码吗

Java 我应该在测试中在实际类中重复代码吗,java,unit-testing,Java,Unit Testing,我想测试一个特定的方法是否能产生预期的结果,但要做到这一点,我还需要在测试中操纵输入 class ToTest { public String produceResponse(String input) { // .... encryptedIds = encryptIds(input) output = doStuff(input, encryptedIds) } public encryptIds(input) { .... } } 在我

我想测试一个特定的方法是否能产生预期的结果,但要做到这一点,我还需要在测试中操纵输入

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

  public encryptIds(input) {
    ....
  }
} 
在我的测试中,我需要检查produceResponse是否实际生成了预期的响应。 为了做到这一点,我必须加密输入中的ID

我的问题是:我应该在测试中重写EncryptID(以便在结果上有更多控制器),还是应该从类本身调用EncryptID

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

  • 切勿将任何生产代码复制到单元测试中,因为它在某些时候会过时。
  • 如果这两种方法都是公共的,则它们是公共API的一部分,因此:

    • 您应该首先对
      encryptIds(String)
      方法的正确行为进行单元测试
    • 然后对
      produceResponse(String)
      方法进行单元测试,该方法将在内部使用已测试的
      encryptIds(String)
      方法
  • 如果
    encryptIds(String)
    不属于公共API的一部分:

    • 然后是不可单元测试的内部实现和助手方法
    • produceResponse(String)
      然后负责加密作为副作用:
      • 如果将其标记为包私有(无修改器),仍然可以对其进行测试
      • 您还可以仅出于测试目的更改
        加密ID(字符串)
        的实现
  • 切勿将任何生产代码复制到单元测试中,因为它在某些时候会过时。
  • 如果这两种方法都是公共的,则它们是公共API的一部分,因此:

    • 您应该首先对
      encryptIds(String)
      方法的正确行为进行单元测试
    • 然后对
      produceResponse(String)
      方法进行单元测试,该方法将在内部使用已测试的
      encryptIds(String)
      方法
  • 如果
    encryptIds(String)
    不属于公共API的一部分:

    • 然后是不可单元测试的内部实现和助手方法
    • produceResponse(String)
      然后负责加密作为副作用:
      • 如果将其标记为包私有(无修改器),仍然可以对其进行测试
      • 您还可以仅出于测试目的更改
        加密ID(字符串)
        的实现
  • 切勿将任何生产代码复制到单元测试中,因为它在某些时候会过时。
  • 如果这两种方法都是公共的,则它们是公共API的一部分,因此:

    • 您应该首先对
      encryptIds(String)
      方法的正确行为进行单元测试
    • 然后对
      produceResponse(String)
      方法进行单元测试,该方法将在内部使用已测试的
      encryptIds(String)
      方法
  • 如果
    encryptIds(String)
    不属于公共API的一部分:

    • 然后是不可单元测试的内部实现和助手方法
    • produceResponse(String)
      然后负责加密作为副作用:
      • 如果将其标记为包私有(无修改器),仍然可以对其进行测试
      • 您还可以仅出于测试目的更改
        加密ID(字符串)
        的实现
  • 切勿将任何生产代码复制到单元测试中,因为它在某些时候会过时。
  • 如果这两种方法都是公共的,则它们是公共API的一部分,因此:

    • 您应该首先对
      encryptIds(String)
      方法的正确行为进行单元测试
    • 然后对
      produceResponse(String)
      方法进行单元测试,该方法将在内部使用已测试的
      encryptIds(String)
      方法
  • 如果
    encryptIds(String)
    不属于公共API的一部分:

    • 然后是不可单元测试的内部实现和助手方法
    • produceResponse(String)
      然后负责加密作为副作用:
      • 如果将其标记为包私有(无修改器),仍然可以对其进行测试
      • 您还可以仅出于测试目的更改
        加密ID(字符串)
        的实现

  • 如果我理解正确,您希望使用已知的EncryptedId作为输入测试
    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进行单元测试,以测试它是否根据字符串输入生成正确的加密ID

    为了测试ToTest类,可以模拟IdEncryptor,这样无论它接收到什么输入,它都会生成所需的encryptedds。例如,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()
    

    如果我理解正确,您希望使用已知的EncryptedId作为输入测试
    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进行单元测试,以测试它是否根据字符串输入生成正确的加密ID

    为了测试ToTest类,可以模拟IdEncryptor,这样无论它接收到什么输入,它都会生成所需的encryptedds。例如,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()
    

    如果我理解正确,您希望使用已知的EncryptedId作为输入测试
    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进行单元测试,以测试它是否根据字符串输入生成正确的加密ID

    为了测试ToTest类,可以模拟IdEncryptor