【问题标题】:JUnits for constructors which uses third party API call使用第三方 API 调用的构造函数的 JUnit
【发布时间】:2017-08-03 11:12:37
【问题描述】:

下面提到的是我需要测试的类:

public class MyClass {
     private String key;
     public MyClass(Connection con) {
         key = ThirdPartyApi.getkey(con);
     }
     public String getKey() {
         return key;
     }
}

现在我需要测试这个构造函数,但是我无法模拟这个第三方 API 调用。测试用例如下所述:

public class MyClassTest{
 @Test
 public void test1(){
     MyClass c = new MyClass(dummyconnection);
     assertNotNull(c.getKey != null);
 }
}

但是这种情况会给我一个错误,即 ThirdPartyAPI 类由于连接对象被模拟而失败。

所以我想模拟这个 ThirdPartyApi 调用。是否可以使用 Easymock、powermock?

【问题讨论】:

  • 你为什么不把键作为参数传递?
  • 我觉得我的问题有点不清楚,我重新编辑了一遍。
  • 我也是这么说的:为什么不直接把key传给构造函数???
  • 正如您所解释的,您想要做的是测试您的getKey() 函数?
  • 好吧,要准确回答您的问题,您正在尝试存根静态方法。 Easymock 不是开箱即用的,这就是为什么您需要使用 PowerMock 的原因 - 它与存根任何其他静态方法完全相同,PowerMock 文档中对此进行了很好的解释。但是,您是否真的应该这样做是另一回事。构造函数应该是一段非常简单的代码,其中没有太多逻辑。如果是我,我会考虑如何以不同的方式设计我的课程。

标签: java junit4 powermock easymock


【解决方案1】:

简单:EasyMock 不支持模拟 static 调用。因此,如果您不想更改您的代码,可以使用 PowerMock(ito) 或 JMockit。

但是更好的 方法是理解使用 static 总是会导致类之间的紧密耦合,并且您要确保这不会影响您对代码进行单元测试的能力。

在你的情况下:

public MyClass(Connection con) {
  key = ThirdPartyApi.getkey(con);

只需将其替换为:

public MyClass(Connection con) {
  this (ThirdPartyApi.getkey(con));
}

/** unit testing only */
MyClass(Key key) {
  ...

瞧,你有一个可以从单元测试中调用的构造函数——现在你只需传递一个 mocked 键对象。而且您的测试将不再执行该静态调用 - 因为您在所有测试中都使用了取键构造函数。

但是您可能需要另一个测试用例来确保调用 public 构造函数会按照您的预期进行 - 并且可能会因为静态调用失败而引发异常。

除此之外:我完全同意 cmets - 你的构造函数做了这么多(包括静态调用)的事实有一定的设计味道。

【讨论】:

    猜你喜欢
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 2017-09-29
    • 2013-01-02
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    相关资源
    最近更新 更多