我有一个对象,它在异步接收到一些消息更改状态后(内部线程更改状态)。状态改变后,我想测试一些行为。测试并发代码的行为
所以基本上我需要做的是这样的:
- 创建对象
- 发送消息到对象
- 等待状态改变
- 测试行为
然而,国家是私人而不是暴露。
有没有一个优雅的解决方案,这不需要暴露状态?
如果没有 - 是否需要更改主代码才能使其更具可测性?
我有一个对象,它在异步接收到一些消息更改状态后(内部线程更改状态)。状态改变后,我想测试一些行为。测试并发代码的行为
所以基本上我需要做的是这样的:
然而,国家是私人而不是暴露。
有没有一个优雅的解决方案,这不需要暴露状态?
如果没有 - 是否需要更改主代码才能使其更具可测性?
如果状态为私有状态,则只能在其自己的类中访问(https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html),这意味着无法在不修改类的情况下从新创建的对象中获取状态。
现在,无论是合理的修改,以做一些测试类是高达几个因素:
所以当然我不能告诉你,如果它是合理的,并无须详细了解软件的组织。
我希望这个简短的答案可以帮助你至少澄清问题。
假设您有权这样做,您可以通过Reflection访问相关的专用字段。
Foo bar = new Foo();
bar.setValue(true);
Field field = Foo.class.getDeclaredField("value");
field.setAccessible(true);
Object value = field.get(bar);
这将得到存储在类中的私有变量的值。
这是非常丑陋的,你可能不应该这样做,但如果你真的需要避免改变你正在测试的类,那么它应该做的伎俩。
测试异步代码的一般模式是阻止主测试线程,而不是在解除主测试线程之前执行的异步回调中声明某些内容。下面是一个使用示例ConcurrentUnit:
final Waiter waiter = new Waiter();
bus.registerMessageHandler(message -> {
waiter.assertEquals(message.body(), "foo");
waiter.resume();
});
waiter.await(5000);
此测试会创建一个等待5秒钟的服务员。根据消息总线注册的回调将在单独的线程中执行断言,然后才能恢复服务器,以便测试可以完成。
这个问题显然需要能够将某种回调/处理程序插入到应用程序中。如果您只是在等待某个状态发生变化,而您完全没有察觉到状态,那么您可以做的很多事情来断言状态发生变化。
可能有一种优雅的方式来通过行为表示状态变化。如果你能详细说明你希望测试的行为,这将有所帮助。你期望有多少种可能的行为?例如,它是否会在状态改变之前返回0,之后是1? – NBartley
正在测试的实际行为并不重要。重点是它只能在状态改变后才能被测试,否则测试是没有意义的。 – traveh