Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.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 如何模拟DefaultMessageListenerContainer_Java_Spring_Mocking_Mockito - Fatal编程技术网

Java 如何模拟DefaultMessageListenerContainer

Java 如何模拟DefaultMessageListenerContainer,java,spring,mocking,mockito,Java,Spring,Mocking,Mockito,我正在努力模拟(使用Mockito)DefaultMessageListenerContainer(org.springframework.jms.listener.DefaultMessageListenerContainer)。这是我的密码: @Mock private DefaultMessageListenerContainer defaultMessageListenerContainer; @Before public void init() { MockitoAnnot

我正在努力模拟(使用Mockito)DefaultMessageListenerContainer(
org.springframework.jms.listener.DefaultMessageListenerContainer
)。这是我的密码:

@Mock
private DefaultMessageListenerContainer defaultMessageListenerContainer;

@Before
public void init() {

    MockitoAnnotations.initMocks( this );
    incomingFeedController = new IncomingFeedControllerImpl();

}

@Test 
public void testHandleConnectionState() { 
    List< DefaultMessageListenerContainer > listeners = 
        new ArrayList< DefaultMessageListenerContainer >(); 
    listeners.add( defaultMessageListenerContainer ); 
    incomingFeedController.setContainers( listeners ); 
    when( defaultMessageListenerContainer.isRunning() ).thenReturn( false );
}
但在junit运行之后,这一行将以:

java.lang.NullPointerException at org.springframework.jms.listener.AbstractJmsListeningContainer.isRunning(AbstractJmsListeningContainer.java:312) at com.source.etf.manager.integrationgateway.feedcontroller.IncomingFeedControllerTest.testHandleConnectionState(IncomingFeedControllerTest.java:37) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59) at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98) at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79) at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87) at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77) at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42) at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88) at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51) at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44) at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27) at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37) at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 我发现
lifecycleMonitor
对象没有被实例化。此对象在顶部的
AbstractJMSListingContainer
中声明:

protected final Object lifecycleMonitor = new Object();

您知道如何正确模拟
DefaultMessageListenerContainer

您仍然需要在正在初始化的对象上设置模拟

我看到您正在测试IncomingFeedControllerImpl,您的模拟对象很可能是此类实例的成员。因为您没有在
IncomingFeedControllerImpl
上显式设置模拟的
DefaultMessageListenerContainer
,所以
AbstractJMSleintingContainer
(可能是
@Autowired
)仍在挂起,没有被模拟


您需要使用setter方法或构造函数来注入它。(您也可以
@Autowired
it)

Mockito不能模拟final类或final方法。这些约束由JVM本身强制执行。模拟这样的代码需要重写类字节码并将其加载到另一个类加载器中。这导致了非常复杂的代码;PowerMock朝着这个方向发展,代码很难维护


另外,不要模仿你不拥有的类型,请参阅上的4-5个第一个结果。为什么需要在单元测试中模拟弹簧类型。您应该创建一些间接方法来避免Spring遵从性,或者编写集成测试;后者似乎更合适,因为它与JMS相关。

您需要使用PowerMock,或者按照@Brice的建议进行集成测试。以下是如何在PowerMock中执行此操作:

@RunWith(PowerMockRunner.class)
@PrepareForTest(DefaultMessageListenerContainer.class)
public class MyTestClass {

    // cannot use the @Mock annotation
    private DefaultMessageListenerContainer defaultMessageListenerContainer;

    @Before
    public void init() {
        // This should allow the mocking of final methods as well.
        defaultMessageListenerContainer = 
            PowerMockito.mock(DefaultMessageListenerContainer.class);
        incomingFeedController = new IncomingFeedControllerImpl();

    }

    @Test 
    public void testHandleConnectionState() { 
        List< DefaultMessageListenerContainer > listeners = 
            new ArrayList< DefaultMessageListenerContainer >(); 
        listeners.add( defaultMessageListenerContainer ); 
        incomingFeedController.setContainers( listeners ); 
        when( defaultMessageListenerContainer.isRunning() ).thenReturn( false );
    }

}
@RunWith(PowerMockRunner.class)
@PrepareForTest(DefaultMessageListenerContainer.class)
公共类MyTestClass{
//无法使用@Mock注释
私有DefaultMessageListenerContainer DefaultMessageListenerContainer;
@以前
公共void init(){
//这也应该允许模拟最终方法。
defaultMessageListenerContainer=
mock(DefaultMessageListenerContainer.class);
incomingFeedController=新的IncomingFeedControllerImpl();
}
@试验
public void testHandleConnectionState(){
列表侦听器=
新建ArrayList();
添加(defaultMessageListenerContainer);
输入FeedController.setContainers(侦听器);
当(defaultMessageListenerContainer.isRunning())。然后返回(false);
}
}

类似的问题:为什么要模拟它?您的代码不应该依赖于
DefaultMessageListenerContainer
,它是一个Spring基础结构组件。事实并非如此。已经试过了。这肯定与未实例化此lifecycleMonitor有关。好吧,根据您的代码,您正试图模拟您的
DefaultMessageListenerContainer
,并通过接收
AbstractJMSleintingContainer
,这意味着从未在您的
IncomingFeedController
上设置模拟对象。我只是复制了此部分,但这是我的测试代码:
@test public void testHandleConnectionState(){Listlisteners=new ArrayList();listeners.add(defaultMessageListenerContainer);incomingFeedController.setContainers(侦听器);when(defaultMessageListenerContainer.isRunning())。然后返回(false);
编辑您的问题并添加测试。是的
@PrepareForTest
指令是强制性的,否则PowerMock不会在临时PowerMock类加载器的域中准备此类
protected final Object lifecycleMonitor = new Object();
@RunWith(PowerMockRunner.class)
@PrepareForTest(DefaultMessageListenerContainer.class)
public class MyTestClass {

    // cannot use the @Mock annotation
    private DefaultMessageListenerContainer defaultMessageListenerContainer;

    @Before
    public void init() {
        // This should allow the mocking of final methods as well.
        defaultMessageListenerContainer = 
            PowerMockito.mock(DefaultMessageListenerContainer.class);
        incomingFeedController = new IncomingFeedControllerImpl();

    }

    @Test 
    public void testHandleConnectionState() { 
        List< DefaultMessageListenerContainer > listeners = 
            new ArrayList< DefaultMessageListenerContainer >(); 
        listeners.add( defaultMessageListenerContainer ); 
        incomingFeedController.setContainers( listeners ); 
        when( defaultMessageListenerContainer.isRunning() ).thenReturn( false );
    }

}
private DefaultMessageListenerContainer createFailingContainer() {
    DefaultMessageListenerContainer container = new DefaultMessageListenerContainer() {
        @Override
        public void start() throws JmsException {
            throw new MyJmsException("TEST");
        }

        @Override
        public void stop() throws JmsException {
            throw new MyJmsException("TEST");
        }
    };
    return container;
}

class MyJmsException extends JmsException {
    private static final long serialVersionUID = 1L;

    public MyJmsException(String msg) {
        super(msg);
    }
}