4

我知道如果我需要模拟一个静态方法,这表明我的设计有一些问题,但就我而言,这似乎不是设计问题。

BundleContext bundleContext = FrameworkUtil.getBundle(ConfigService.class).getBundleContext();

这里 FrameworkUtil 是一个存在于 api jar 中的类。在代码中使用它不是设计问题。

我的问题是在运行这条线时

FrameworkUtil.getBundle(ConfigService.class); 

返回 null 所以我的问题是,有什么方法可以在运行时替换该 null 我正在使用 Mockito 框架,而我的项目不允许我使用 powermock。

如果我使用

doReturn(bundle).when(FrameworkUtil.class)

这样 getBundle 方法是不可见的,因为它是一个静态方法。

4

2 回答 2

9

你是对的,这不是你的设计问题。但是,如果没有 PowerMock,您的选择会变得有些模糊。

我建议为您可以注入和模拟的 FrameworkUtil 类创建一个非静态包装器。

更新:(大卫华莱士)

所以你向你的应用程序添加一个新类,像这样

public class UtilWrapper {
    public Bundle getBundle(Class<?> theClass) {
        return FrameworkUtil.getBundle(theClass);
    }
}

这个类非常简单,你不需要对它进行单元测试。作为一般原则,您应该只为具有某种逻辑的方法编写单元测试——分支、循环或异常处理。单行不应该进行单元测试。

现在,在您的应用程序代码中,UtilWrapper为当前调用的每个类添加一个 type 字段和一个 setter FrameworkUtil.getBundle。将此行添加到每个此类的构造函数

utilWrapper = new UtilWrapper();

并将每次调用替换FrameworkUtil.getBundleutilWrapper.getBundle.

现在在您的测试中,您制作一个模拟UtilWrapper并将其存根以返回Bundle您喜欢的任何内容。

when(mockUtilWrapper.getBundle(ConfigService.class)).thenReturn(someBundleYouMade);

对于您正在测试的课程,请致电setUtilWrapper(mockUtilWrapper)或其他任何方式。如果您使用@InjectMocks.

现在你的测试应该全部挂在一起,但是使用你的 mockedUtilWrapper而不是依赖FrameworkUtil.

于 2013-11-13T05:50:43.027 回答
2

单元测试

package x;

import static org.junit.Assert.*;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;

public class GunTest {

  @Before
  public void setUp() throws Exception {
  }

  @Test
  public void testFireTrue() {
    final Gun unit = Mockito.spy(new Gun());
    Mockito.doReturn(5).when(unit).getCount();
    assertTrue(unit.fire2());
  }

  @Test
  public void testFireFalse() {
    final Gun unit = Mockito.spy(new Gun());
    Mockito.doReturn(15).when(unit).getCount();
    assertFalse(unit.fire2());
  }

}

单元:fire 直接调用静态方法,fire2 将静态调用分解为受保护方法:

package x;

public class Gun {

  public boolean fire() {
    if (StaticClass.getCount() > 10) {
      return false;
    }
    else {
      return true;
    }
  }

  public boolean fire2() {
    if (getCount() > 10) {
      return false;
    }
    else {
      return true;
    }
  }

  protected int getCount() {
    return StaticClass.getCount();
  }
}
于 2013-11-13T06:15:25.533 回答