Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用PowerMock-EasyMock时发生意外的方法调用_Java_Mocking_Easymock_Powermock - Fatal编程技术网

Java 使用PowerMock-EasyMock时发生意外的方法调用

Java 使用PowerMock-EasyMock时发生意外的方法调用,java,mocking,easymock,powermock,Java,Mocking,Easymock,Powermock,我的问题似乎是对嘲笑的误解。用于测试的代码 public class CallHandler { private SqlSessionFactory sessionFactory; public CallHandler() { String resource = "mybatis/mybatis-config.xml"; Reader reader; try { reader = Resources.getR

我的问题似乎是对嘲笑的误解。用于测试的代码

public class CallHandler {
    private SqlSessionFactory sessionFactory;
    public CallHandler() {
        String resource = "mybatis/mybatis-config.xml";
        Reader reader;
        try {
            reader = Resources.getResourceAsReader(resource);
            sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String handleRequest(Call call) {
        // Some Implementation
    }
}
考试班

// I have excluded few unnecessary classes from @PrepareForTest for the post.

@RunWith(PowerMockRunner.class)
@PrepareForTest({SqlSessionFactoryBuilder.class, Resources.class, SqlSessionFactory.class, SqlSession.class})
public class TestCase0 extends TestCase{
    private SqlSessionFactory mockedSessionFactory = PowerMock.createMock(SqlSessionFactory.class);
    private SqlSession mockedSession = PowerMock.createMock(SqlSession.class);
    private CallMapper mockedMapper = PowerMock.createMock(CallMapper.class);
    private SqlSessionFactoryBuilder mockedSqlSessionFactoryBuilder= PowerMock.createMock(SqlSessionFactoryBuilder.class);
    // Others

    @Before
    public void setUp() {
    }

    @Test
    public void test0 () throws Exception {
        mockStatic(CallMapper.class);
        mockStatic(SqlSessionFactoryBuilder.class);
        mockStatic(Resources.class);
        expect(Resources.getResourceAsReader("mybatis/mybatis-config.xml")).andReturn(mockedReader);      expectNew(SqlSessionFactoryBuilder.class).andReturn(mockedSqlSessionFactoryBuilder);  expect(mockedSqlSessionFactoryBuilder.build(mockedReader)).andReturn(mockedSessionFactory);
        expect(mockedSessionFactory.openSession()).andReturn(mockedSession);
        // Few more expectations
        replayAll();
        assertThat(RESULT0).isEqualTo((new CallHandler()).handleRequest(call));
        verifyAll();
    }
}
在新的
SqlSessionFactoryBuilder
上模拟调用build似乎没有生效,因为调用了原始的
build()
,因此出现了错误。堆栈跟踪

java.lang.AssertionError: 
Unexpected method call Reader.close();
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:44)
at org.powermock.api.easymock.internal.invocationcontrol.EasyMockMethodInvocationControl.invoke(EasyMockMethodInvocationControl.java:91)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:168)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:58)
at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:38)
at com.kwench.integration.ivr.CallHandler.<init>(CallHandler.java:48)
at in.kwench.integration.ivr.TestCase0.test0(TestCase0.java:131)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:104)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
java.lang.AssertionError:
意外的方法调用读取器.close();
位于org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:44)
位于org.powermock.api.easymock.internal.invocationcontrol.EasyMockMethodInvocationControl.invoke(EasyMockMethodInvocationControl.java:91)
位于org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105)
位于org.powermock.core.MockGateway.methodCall(MockGateway.java:168)
位于org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:58)
位于org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:38)
位于com.kwench.integration.ivr.CallHandler。(CallHandler.java:48)
位于in.kwench.integration.ivr.TestCase0.test0(TestCase0.java:131)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:606)
位于org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
位于org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
位于org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88)
位于org.junit.internal.runners.MethodRoadie.runbeforesthentestthenuter(MethodRoadie.java:96)
位于org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
位于org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
位于org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
位于org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runbeforesthenTesttheAfter(PowerMockJUnit44RunnerDelegateImpl.java:282)
位于org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
位于org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
位于org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateinpl.invokeTestMethod(powermockjunit44runnerdelegateinpl.java:207)
位于org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateinpl.runMethods(powermockjunit44runnerdelegateinpl.java:146)
位于org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateinpl$1.run(powermockjunit44runnerdelegateinpl.java:120)
位于org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
位于org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
位于org.powermock.modules.junit4.internal.impl.powermockjunit44runnerdelegateinpl.run(powermockjunit44runnerdelegateinpl.java:118)
位于org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:104)
位于org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
位于org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
位于org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)

如果没有您正在测试的代码和测试类本身的完整示例,很难说问题会出现在哪里

话虽如此,我猜您的问题在于您没有准备使用静态方法的类。这些需要在测试类开始时的@PrepareForTest注释中提供

PowerMock的文档提供了以下模拟静态方法的技巧。我猜你错过了第二点

模拟静态方法 快速总结

  • 在测试用例的类级别使用@RunWith(PowerMockRunner.class)注释
  • 在测试用例的类级别使用@PrepareForTest(包含StaticMethod.class的类)注释
  • 使用PowerMock.mockStatic(包含StaticMethod.class的类)来模拟此类的所有方法
  • 使用PowerMock.replay(包含StaticMethod.class的类)将类更改为replay模式
  • 使用PowerMock.verify(包含StaticMethod.class的类)将类更改为验证模式
  • 你也嘲笑构造函数调用<代码> SqlSessionFactoryBuilder <代码>,所以你也需要考虑这个技巧。 新对象的模拟构造 快速总结

  • 在测试用例的类级别使用@RunWith(PowerMockRunner.class)注释
  • 在测试用例的类级别使用@PrepareForTest(创建NewInstance.class的类)注释
  • 使用PowerMock.createMock(NewInstanceClass.class)创建应该构造的类的mock对象(我们称之为mockObject)
  • 使用PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject)来预期NewInstanceClass.class类型的对象的新构造,但返回模拟对象
  • 使用PowerMock.replay(mockObject,NewInstanceClass.class)将模拟对象和类更改为重播模式,或者使用PowerMock.replayAll()方法
  • 使用PowerMock.verify(mockObject,NewInstanceClass.class)更改模拟对象和类以验证模式,或者使用PowerMock.verifyAll()me
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({CallHandler.class, SqlSessionFactoryBuilder.class, Resources.class})
    public class CallHandlerTest {
    
        private static final String RESULT0 = "";
    
        @Test
        public void test0 () throws Exception {
            final Reader mockedReader = EasyMock.createMock(Reader.class);
            final SqlSessionFactoryBuilder mockedSqlSessionFactoryBuilder = EasyMock.createMock(SqlSessionFactoryBuilder.class);
            final SqlSessionFactory mockedSessionFactory = EasyMock.createMock(SqlSessionFactory.class);
    
            PowerMock.mockStatic(SqlSessionFactoryBuilder.class);
            PowerMock.mockStatic(Resources.class);
    
            PowerMock.expectNew(SqlSessionFactoryBuilder.class).andReturn(mockedSqlSessionFactoryBuilder);
            EasyMock.expect(Resources.getResourceAsReader("mybatis/mybatis-config.xml")).andReturn(mockedReader);
            EasyMock.expect(mockedSqlSessionFactoryBuilder.build(mockedReader)).andReturn(mockedSessionFactory);
    
            PowerMock.replayAll();
            assertThat(RESULT0).isEqualTo((new CallHandler()).handleRequest(new Call()));
            PowerMock.verifyAll();
        }
    }