Spring - 如何使用ApplicationEventPublisher依赖项测试Controller?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring - 如何使用ApplicationEventPublisher依赖项测试Controller?相关的知识,希望对你有一定的参考价值。

我有一个发布活动的Controller

@RestController
public class Controller
{
    @Autowired
    private ApplicationEventPublisher publisher;

    @GetMapping("/event")
    public void get()
    {
        publisher.publishEvent(new Event());
    }
}

现在我想测试该事件是否已发布。首先,我尝试@MockBean ApplicationEventPublisher并验证方法调用。但根据https://jira.spring.io/browse/SPR-14335,这不起作用

所以我这样做:

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = Controller.class)
public class ControllerTest
{
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void getTest() throws Exception
    {
        this.mockMvc.perform(get("/").contentType(MediaType.APPLICATION_JSON)
                    .andExpect(status().isOk());
        assertNotNull(Listener.event);
    }

    @TestConfiguration
    static class Listener
    {
        public static Event event;

        @EventListener
        void listen ( Event incoming )
        {
            event = incoming;
        }
    }
}

这种常见用例有更简单的方法吗?

答案

你可以这样做

@RunWith(SpringRunner.class)
public class ControllerTest {

    private MockMvc mockMvc;

    @MockBean
    private ApplicationEventPublisher publisher;

    @Before
    public void setup() {
        Controller someController= new Controller(publisher);
        mockMvc = MockMvcBuilders.standaloneSetup(someController).build();
    }

    @Test
    public void getTest() throws Exception
    {
        ArgumentCaptor<Event> argumentCaptor = ArgumentCaptor.forClass(Event.class);
        doAnswer(invocation -> {
            Event value = argumentCaptor.getValue();
             //assert if event is correct
            return null;
        }).when(publisher).publishEvent(argumentCaptor.capture());  

        this.mockMvc.perform(get("/").contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());

        verify(publisher, times(1)).publishEvent(any(Event.class));
    }

}  

并且还在控制器类中将Field Injection更改为Constructor Injection(这是一个很好的做法)。

@RestController
public class Controller
{

  private ApplicationEventPublisher publisher;

  @Autowired
  public Controller(ApplicationEventPublisher publisher) {
      this.publisher = publisher;
  }
 ....
}

以上是关于Spring - 如何使用ApplicationEventPublisher依赖项测试Controller?的主要内容,如果未能解决你的问题,请参考以下文章

请简述啥是CSS3 Spring?如何使用Spring

spring中如何使用策略模式

如何将 Spring 与 JavaFX 一起使用?

如何使用 Spring 重新加载属性?

Spring-batch:如何在 Spring Batch 中使用 skip 方法捕获异常消息?

如何在 Spring webflux 应用程序中使用 Spring WebSessionIdResolver 和 Spring Security 5?