【问题标题】:Passing System properties into a void method in jUnit将系统属性传递给 jUnit 中的 void 方法
【发布时间】:2015-08-04 14:05:44
【问题描述】:

我正在尝试使用 Hazelcast 对一些代码进行单元测试。大部分代码都很简单,但我一直在使用类构造函数。

private final static Logger LOGGER = Logger.getLogger(ClientViewer.class);
protected static HazelcastInstance client;

public ClientViewer() {
    setup();
}

private void setup() {
    ClientConfig clientConfig = new ClientConfig();
    clientConfig.getGroupConfig.setName(System.getProperty("hazelcast.group")).setPassword(System.getProperty("hazelcast.password"));
    clientConfig.getNetworkConfig().addAddress(System.getProperty("hazelcast.url"));
    client= HazelcastClient.newHazelcastClient(clientConfig);
}

因此,每当我尝试创建一个测试对象来调用/测试其方法时,它都会不断抛出 IllegalArgumentException。所以我决定在使用测试数据创建测试对象之前单独设置每个属性。

TEST_GROUP = "testGroup";
TEST_PASSWORD = "testPassword";
TEST_URL = "testUrl";

System.setProperty("hazelcast.group", TEST_GROUP);
System.setProperty("hazelcast.password", TEST_PASSWORD);
System.setProperty("hazelcast.url", TEST_URL);

但现在我收到了 InvocationTargetException。我错过了什么?有没有办法在不依赖注入的情况下欺骗设置方法?

(顺便说一句:我知道依赖注入是一种明显的好习惯,但这种想法在我的同行中有些丢失。可以说,在这种情况下这不是一个选择。)

【问题讨论】:

  • 依赖注入可能是一个好主意,也可能不是一个好主意,但是为什么要直接在类中读取系统属性?您可以使用setProperties(Map<String, String>) 方法,然后您的实时代码可以插入系统属性,而您的测试代码可以使用其他的。无论如何,发布异常是个好主意...
  • InvalidArgumentException 如果我没记错的话。从那时起,我进行了各种调整。我想看看我是否可以使用 any() 方法以某种方式模拟 HazelcastClient,但到目前为止还没有运气。现在它抱怨 key log4j.appender.stdout 的值。我会相应地编辑代码。
  • 如果没有当前准确的错误消息,恐怕您找到可以帮助您的人的机会会大大降低。
  • 为什么不重构代码,以便将所有参数作为参数提供,而另一个方法只是调用此方法并读取所有属性并将其传递给该方法。这大大简化了测试,因为您可以在测试时轻松提供这些方法。我认为您不想运行集成测试来测试从System.getProperties(...) 获取值是否真的有效?也可以试试mock System.getProperty(...)
  • 我有几个关于呈现的代码和单元测试的问题。测试System.getProperty(...) 已经由您选择的JVM 供应商完成(希望如此)。此外,Hazelcast 客户端的初始化测试已经由 Hazelcast 完成。测试构造函数不会返回任何东西 - 因此您需要白盒测试。在我看来,模拟所有的外部类也是没用的,因为真正测试的是什么?使用提供的属性创建一个真正的 Hazelcast 客户端已经是一个集成测试!

标签: java unit-testing junit system hazelcast


【解决方案1】:

让我一劳永逸地解决这个问题。我刚刚在 PowerMock 中发现了一个名为 Whitebox 的东西,它抑制了类的构造函数。

final ClientViewer testObject = newInstance(ClientViewer.class);
testObject.client = mockHazelcastInstance;

通过将上面的代码放在你的测试方法中,我们完全绕过了那个讨厌的 setup() 方法,并用一个模拟的类替换了类的客户端属性。这将允许我们验证客户端的行为,而无需初始化 Hazelcast 实例。

这花了我三天的时间才弄明白。我是在最后五分钟才发现的。对于我可能造成的任何麻烦或困惑,我深表歉意,我当然感谢您的所有帮助。谢谢。

【讨论】:

    猜你喜欢
    • 2019-01-31
    • 2015-03-18
    • 2019-06-22
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    • 1970-01-01
    相关资源
    最近更新 更多