我有一个对象,它在收到一些消息后异步改变状态(内部线程改变状态)。状态改变后我想测试一些行为。
所以基本上我需要做一些事情:
但是,状态是私有并且未公开。
是否有一个优雅的解决方案,不需要暴露状态?
如果不是 - 要求更改主代码以使其更易于测试是否合理?
答案 0 :(得分:1)
测试异步代码的一般模式是阻塞主测试线程,而不是在取消阻塞主测试线程之前执行异步回调中的某些内容。以下是使用ConcurrentUnit的示例:
final Waiter waiter = new Waiter();
bus.registerMessageHandler(message -> {
waiter.assertEquals(message.body(), "foo");
waiter.resume();
});
waiter.await(5000);
此测试会创建一个等待5秒钟的服务员。针对消息总线注册的回调将在恢复服务员之前在单独的线程中执行断言,以便测试可以完成。
问题是你显然需要能够将某种回调/处理程序插入到应用程序中。如果你只是在等待一些状态改变而你完全无法看到它,那么就没有太多可以断言状态发生了变化。
答案 1 :(得分:-1)
如果状态是私有的,则只能在其自己的类(https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html)中访问它,这意味着如果不修改类,您将无法从新创建的对象中获取状态。
现在,为了进行一些测试而修改类是否合理是多种因素:
因此,如果不详细了解您的软件组织,我无法告诉您这是否合理。
我希望这个简短的回答可以帮助你解决问题。
答案 2 :(得分:-1)
您可以使用Reflection访问相关的私有字段,假设您有权这样做。
Foo bar = new Foo();
bar.setValue(true);
Field field = Foo.class.getDeclaredField("value");
field.setAccessible(true);
Object value = field.get(bar);
这将获得存储在类中的私有变量中的值。
这非常难看,你可能不应该这样做,但是如果你真的需要避免改变你正在测试的课程那么它应该可以做到。