2015-07-21 66 views
0

我有一个对象,它在异步接收到一些消息更改状态后(内部线程更改状态)。状态改变后,我想测试一些行为。测试并发代码的行为

所以基本上我需要做的是这样的:

  1. 创建对象
  2. 发送消息到对象
  3. 等待状态改变
  4. 测试行为

然而,国家是私人而不是暴露。

有没有一个优雅的解决方案,这不需要暴露状态?

如果没有 - 是否需要更改主代码才能使其更具可测性?

+0

可能有一种优雅的方式来通过行为表示状态变化。如果你能详细说明你希望测试的行为,这将有所帮助。你期望有多少种可能的行为?例如,它是否会在状态改变之前返回0,之后是1? – NBartley

+0

正在测试的实际行为并不重要。重点是它只能在状态改变后才能被测试,否则测试是没有意义的。 – traveh

回答

-1

如果状态为私有状态,则只能在其自己的类中访问(https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html),这意味着无法在不修改类的情况下从新创建的对象中获取状态。
现在,无论是合理的修改,以做一些测试类是高达几个因素:

  • 有多少人对代码的工作?
  • 有多少人已经在使用该代码的以前版本?
  • 如果将状态变量更改为public并添加getter方法,您将面临的完整性问题。

所以当然我不能告诉你,如果它是合理的,并无须详细了解软件的组织。
我希望这个简短的答案可以帮助你至少澄清问题。

-1

假设您有权这样做,您可以通过Reflection访问相关的专用字段。

Foo bar = new Foo(); 
    bar.setValue(true); 

    Field field = Foo.class.getDeclaredField("value"); 
    field.setAccessible(true); 
    Object value = field.get(bar); 

这将得到存储在类中的私有变量的值。

这是非常丑陋的,你可能不应该这样做,但如果你真的需要避免改变你正在测试的类,那么它应该做的伎俩。

+0

我很清楚有很多丑陋的解决方案。我的问题是,如果有一个*优雅的解决方案*,而不是一个丑陋的... – traveh

+0

没有修改你正在测试的类,这是你将得到最优雅。测试课是我甚至建议这样做的少数几个地方之一。因为这是一个可行的答案,所以对我来说投票似乎很难。 –

+0

这就是我所怀疑的,为什么我问了问题的第二部分。我最初的想法是将状态改为受保护的,从类继承,并使用继承的类进行测试,但它让我觉得这样做有些激进(尤其是改变对每个度量应该是私有的状态的访问除了测试的缘故)。但我想没有好的选择。 – traveh

1

测试异步代码的一般模式是阻止主测试线程,而不是在解除主测试线程之前执行的异步回调中声明某些内容。下面是一个使用示例ConcurrentUnit

final Waiter waiter = new Waiter(); 

bus.registerMessageHandler(message -> { 
    waiter.assertEquals(message.body(), "foo"); 
    waiter.resume(); 
}); 

waiter.await(5000); 

此测试会创建一个等待5秒钟的服务员。根据消息总线注册的回调将在单独的线程中执行断言,然后才能恢复服务器,以便测试可以完成。

这个问题显然需要能够将某种回调/处理程序插入到应用程序中。如果您只是在等待某个状态发生变化,而您完全没有察觉到状态,那么您可以做的很多事情来断言状态发生变化。