首页 > 解决方案 > ApplicationContext.getBeansOfType 改变返回的映射 - WebFluxTest SpringBoot

问题描述

我正在尝试进行控制器测试。我在控制器中测试 applicationContext.getBeansOfType 时发现了一些困难。

所以这里是我的控制器代码的片段看起来像

@RestController
@RequestMapping(value = "/api/bridge")
public class BridgeController {

    @RequestMapping(
      value = "/visitor",
      method = RequestMethod.POST
    )
    public Mono<Response<Boolean>> visitorEvent(
      @RequestBody VisitorEventWebRequest webRequest) {

      return Mono
          .fromCallable(() -> constructVisitorEventCommandRequest(webRequest))
          .flatMap(register -> 
              commandExecutor.execute(getVisitorFactory(webRequest).getClass(),register)
              .subscribeOn(SchedulerHelper);
     }
}

使用 getVisitorFactory(webRequest) 是一种基于其 eventType 调用服务的 beans 实例的方法(这是 webRequest 中的一个字段)

private VisitorEventAbstract getVisitorFactory(VisitorEventWebRequest webRequest) {
    try {
      VisitorEventAbstract command = this.applicationContext.getBeansOfType(VisitorEventAbstract.class)
          .getOrDefault(webRequest.getEventType(), null);

      if(command == null) {
        throw new RuntimeException();
      }

      return command;
    } catch (Exception e) {
      log.error("Error getting visitor event abstract implementation for event type : {}",
          webRequest.getEventType());
      throw new RuntimeException();
    }
}

然后,在我的控制器测试中,我模拟了 applicationContext.getBeansOfType,它将返回我在 @Before 方法中声明的映射。我正在使用 SpringExtension 和 WebFluxTest。片段如下

@ExtendWith(SpringExtension.class)
@WebFluxTest(controllers = BridgeController.class)
public class BridgeVisitorControllerTest {

   @Autowired
   private WebTestClient testClient;

   @MockBean
   private ApplicationContext applicationContext;

   @MockBean
   private RegisterEventCommandImpl registerEventCommandImpl;

   private Map<String, VisitorEventAbstract> visitorEventAbstractContext;

   @BeforeEach
   public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);

    this.visitorEventAbstractContext = new HashMap<>();
    this.visitorEventAbstractContext.put("REGISTRATION", this.registerEventCommandImpl);
  }

  @Test
  public void execute() {

   /// some code

   when(applicationContext.getBeansOfType(VisitorEventAbstract.class))
        .thenReturn(this.visitorEventAbstractContext);
   when(commandExecutor.execute(eq(VisitorEventAbstract.class), any()))
        .thenAnswer(ans -> Mono.just(Boolean.TRUE));

   /// testClient.post()

  }
}

因此,由于我已经初始化了地图,并模拟了 applicationContext,我希望当 controllerTest 运行时,在 getVisitorFactory(webRequest 方法)中,它会像这样返回地图

{ "key" : "REGISTRATION", "value" : RegisterEventCommandImpl (已被模拟的 bean 实例) }

但实际上,返回的地图总是像这样改变键:

{ "key" : "{RegisterEventCommandImpl 的包名}", "value" : RegisterEventCommandImpl (bean instance) }

这使我的测试总是失败,因为他们找不到键为“注册”的 bean。请帮忙,我错过了什么?为什么关键总是这样改变?

谢谢您的回答。

标签: javaspringspring-bootunit-testingspring-webflux

解决方案


推荐阅读