whenNew或expectNew在模拟时没有调用真正的构造函数

时间:2017-05-04 11:43:32

标签: mocking powermock powermockito

我正在嘲笑使用all - powerMock / PowerMockito以及那里可用的任何东西来模拟我的构造函数。

这是我在其中调用Spring的新构造函数的类。

  public class BaseService {
        private void loadSpringConfig(String customResourceName) {
          String[] resources = new String[1];
          resources[0] = "test.xml";
          context = new ClassPathXmlApplicationContext(resources);
        }
}

这是我在模拟中使用的代码。使用wehnNew以及expectNew调用'ClassPathXmlApplicationContext'构造函数并给出文件未找到异常。

@RunWith(PowerMockRunner.class)
@PrepareForTest({BaseService.class, 
   ClassPathXmlApplicationContext.class})
public class BaseServiceTest {
    @Mock
    ClassPathXmlApplicationContext ctx;
    @Test
    public void loadSpringConfigTest() throws Exception{

        //ClassPathXmlApplicationContext ctx = PowerMockito.mock(ClassPathXmlApplicationContext.class);
        Method method;
        String[] resources = new String[1];
        resources[0]="test.xml";
        BaseService bs = new BaseService();
        try {
            method = BaseService.class.getDeclaredMethod("loadSpringConfig",String.class);
            method.setAccessible(true);
            //trowing exception of file not found - tried various option with no luck 
            PowerMockito.whenNew(ClassPathXmlApplicationContext.class).withAnyArguments().thenReturn(ctx);
//Other tries
//withParameterTypes(String[].class).withArguments(resources).thenReturn(ctx);
            //PowerMock.expectNew(ClassPathXmlApplicationContext.class,new Class[]{String[].class},resources).andReturn(ctx);
            method.invoke(bs,"test");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
}

1 个答案:

答案 0 :(得分:0)

深入探索PowerMock黑暗权力......当答案如此简单:避免召唤新的。

今天在生产代码中调用new是(经常,并非总是)错误的事情。它使代码比应该更难测试。

因此:

  • 学习如何创建易于测试的代码;例如,通过观看这些videos
  • 而不是调用new,使用依赖注入,并为您的类提供一个简单的工厂,可用于获取此类上下文。

不再new;并且您可以使用那种"黑魔法"进行所有测试。另外:产品质量也会提高。

关于后续问题 - 您已经模拟了要注入的对象?!

@Mock
ClassPathXmlApplicationContext ctx;

创建一个模拟的 ClassPath..Context对象。您可能希望/必须通过/例如调用来配置它。