单元测试具有模拟

时间:2016-07-29 01:06:55

标签: java unit-testing serialization mocking mockito

我遇到的问题是,如果某个特定的类是可序列化的,那么单元测试时,另一个类的模拟对象不可定制。

这是一个小程序,用于说明问题。我有一个需要序列化的 处理器 类, RpcClient 是一个不可序列化的类。为了使 Processor 可序列化,我将 rpcClient 成员变量标记为 transient

class RpcClient {
  int addr;

  RpcClient(int addr) {
    this.addr = addr;
    // connect to remote service
  }

  // other methods
}

class RpcClientFactory implements Serializable {
  public RpcClient getRpcClient(int addr) {
    return new RpcClient(addr);
  }
}

class Processor implements Serializable {
  final RpcClientFactory rpcClientFactory;
  transient RpcClient rpcClient;

  Processor() {
    this(new RpcClientFactory());
  }

  Processor(RpcClientFactory rpcClientFactory) {
    this.rpcClientFactory = rpcClientFactory;
  }

  public void start(int addr) {
    rpcClient = rpcClientFactory.getRpcClient(addr);
  }

  // other methods
}

现在为了测试 Processor 类,我有以下单元测试,

@RunWith(JUnit4.class)
public class ProcessorTest {
  private RpcClientFactory mockRpcClientFactory;
  private RpcClient mockRpcClient;

  @Before
  public void setUp() {
    mockRpcClientFactory = mock(RpcClientFactory.class, withSettings().serializable());
    mockRpcClient = mock(RpcClient.class, withSettings().serializable());
    when(mockRpcClientFactory.getRpcClient(any(int.class))).thenReturn(mockRpcClient);
  }

  @Test
  public void testProcessorIsSerializable() {
    Processor p = new Processor(rpcClientFactory);
    p.start();
    // Use some Utils library to serialize and deserialize 
    Utils.deserializeFromByteArray(Utils.serializeToByteArray(p));

    assert(true);
  }
}

运行测试失败,但有例外,

Caused by: java.io.InvalidClassException: ProcessorTest$RpcClient$$EnhancerByMockitoWithCGLIB$$5db6cf07; no valid constructor

当然,如果我向 RpcClient 添加一个no-arg构造函数,问题就会消失,但我们可以说它是我无法访问的第三方库。我明白 Mockito 明确提到, 假设所有正常的序列化要求都由类 和我的案例 RpcClient 不符合要求。

但是如果你看一下,即使我的代码不希望 RpcClient 可序列化(标记为瞬态),我的单元测试也会迫使我这样做。有没有办法在我的测试课中解决这个问题?

0 个答案:

没有答案