事件中设置的 ServletContextListener 属性为空

ServletContextListener attribute set in event is null

我有一个如下所示的 ServletContextListener

public class MyServletContextListener implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
    System.out.println("Start");
    servletContextEvent.getServletContext().setAttribute("id1", "this is my value");
    System.out.println("Current value is" + servletContextEvent.getServletContext().getAttribute("id1"));
    System.out.println("End");
}

这将打印:

Start
Current value is null
End

是的,监听器定义在web.xml:

<listener>
    <listener-class>package.path.MyServletContextListener</listener-class>
</listener>

我错过了什么?

乐: 我在我的单元测试中获得了这个(使用 junit 和 mockito)。在我的 TestClass 中,我有一个 @BeforeClass 方法,我在其中执行以下操作:

ServletRunner sr = new ServletRunner(new File("src/test/resources/WEB-INF/web.xml"));
ServletUnitClient sc = sr.newClient();

listener = new MyServletContextListener ();

    event = mock(ServletContextEvent.class);
    servletContext = mock(ServletContext.class);

    when(event.getServletContext()).thenReturn(servletContext);

    listener.contextInitialized(event);

问题似乎出在您的 ServletContext 模拟中。你通过 Mockito.mock(ServletContext.class) 创建它,Mockito 足够聪明,可以提供一个实现所有 ServletContext 方法的对象,但你怎么认为它会知道什么 行为 实施?

它本身不能,仅靠界面 class 无法继续。 Mockito 所能做的就是提供具有正确签名的存根。你没有做任何事情(在你展示的内容中)来提供模拟的 setAttribute() 方法来实际记录设置的属性,或者它的 getAttribute() 方法来查找和 return目的。看来 Mockito 可以支持它,但您需要告诉它该做什么。

另请注意,如果重点是验证 contextInitialized() 方法是否设置了属性,那么最好的检查方法是检测 ServletContext 模拟,而不是观察侦听器的输出System.out。依赖输出也会将其纳入测试范围,因此现在您正在联合测试两个不同的功能。