我遇到的问题是,如果某个特定的类是可序列化的,那么单元测试时,另一个类的模拟对象不可定制。
这是一个小程序,用于说明问题。我有一个需要序列化的 处理器 类, 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 可序列化(标记为瞬态),我的单元测试也会迫使我这样做。有没有办法在我的测试课中解决这个问题?