unit-testing - Mockist tdd : How to test UUT when collaborator can only be constructed inside UUT?

标签 unit-testing mocking tdd bdd

我正在尝试对名为 StringReader 的 Java 对象进行行为测试。代码看起来像这样:

public interface CharReader {
  public char readChar();
}    

public class ByteArrayCharReader implements CharReader {
  public ByteArrayCharReader(byte[] bytes);
  public char readChar();
}

public class StringReader {
  public String readString(byte[] bytes);
}

StringReader 的协议(protocol)/职责是:

  • 当调用 readString 时,StringReader 应重复调用 CharReader.readChar() 从字节数组中读取字符,直到遇到空终止字符或最大字符数(20)。这个想法是 StringReader 不应该为正确的 unicode 字符解码中的所有组成部分而烦恼,这样的责任就委托(delegate)给了 CharReader。

我想为 StringReader 编写一个表达此协议(protocol)的单元测试,但我似乎不知道如何实现。

首先,我以为我只是希望 StringReader 在内部创建一个 ByteArrayCharReader 并在 readString() 中传递的字节数组上使用它,但这似乎没有意义,因为这样我就无法从外部模拟它.

看来我遇到了先有鸡还是先有蛋的问题。我想将 ByteArrayCharReader 注入(inject)到 StringReader 中,但是 ByteArrayCharReader 必须使用一个字节数组来构造,该数组仅在调用 readString 时才首先可用 - 那么如果我无法从外部构造/模拟它,我如何传递它?这似乎是一个愚蠢的问题,因为理论上我知道传递给 readString 的字节数组实际上来自 ByteArrayCharReader 也来自的测试,所以我确实已经准备好参数“在那里”。也许我错过了什么?

我应该提到,我正在开发遗留代码库,因此我无法轻松更改 StringReader.readString 的接口(interface)。

我有点沮丧,我不知道如何解决这个问题,因为这似乎是一个非常简单的场景; A 传递了一个数组并想要使用 ArrayParser 解析该数组 - 如何测试其行为(不是基于状态)?

最佳答案

您可以使用factory method pattern 。您只需注入(inject)工厂,而不是注入(inject)/实例化 ByteArrayCharReader ,该工厂的纯粹工作是提供所请求的读取器的实例:

public class ReadersFactoryImpl implements ReadersFactory {
    public CharReader CreateByteReader(byte[] content) {
        return new ByteArrayCharReader(content);
    }
}

仅此而已。您可以轻松地模拟它并对其进行设置,以便它返回另一个模拟。测试 StringReader 是否按预期调用其他读取器应该足够了。

关于unit-testing - Mockist tdd : How to test UUT when collaborator can only be constructed inside UUT?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9672889/

相关文章:

java - 使用 Mockito 对 Runnable 进行单元测试

java - 尝试找到使用mockito调用匿名内部回调的最佳实践

c# - 如何使用 TDD 方法创建 Restful Web 服务?

python - unittest.TestCase 中的 setUp 方法是否知道当前的测试用例?

java - 测试弱引用

java - 如何使用 JUnit 和 Mockito 来模拟内部逻辑

c# - 集成测试是否应该重做使用模拟的单元测试?

unit-testing - Debug.Assert 会干扰 MSTests,我该如何解决它?

mocking - 你应该只模拟你拥有的类型吗?

c# - 设置 Moq 以忽略虚拟方法