【问题标题】:Elasticsearch - Junit tests (mock or fill SearchResponse)Elasticsearch - Junit 测试(模拟或填充 SearchResponse)
【发布时间】:2018-11-18 10:01:53
【问题描述】:

我使用 Elastic 6.2、SpringBoot、Java 8。

@RestController
@Log4j2
@AllArgsConstructor
@RequestMapping("/api/logs")
public class ElasticRestController {
 @PostMapping("/search")
    public GenericResponse<?> findLogs(@RequestBody ESLogRequestDTO esLogRequest,
                                       Pageable pageable) throws NoConnectionException {
        SearchResponse searchResponse = elasticUIService.
                findLogsByParameters(esLogRequest, pageable);
        return GenericResponse.
                success(convertToStandardResponse(searchResponse.getHits(), pageable));
    }
}

这里是 JUnit 控制器测试,在 json(searchRequest) 中有一些填充请求:

@WebMvcTest(
        value = ElasticRestController.class,
        secure = false
)
public class ElasticRestControllerTest extends AbstractControllerTest {

    private static final String CONTENT_TYPE = "application/json;charset=UTF-8";

    @MockBean
    private ElasticUIService elasticUIService;

    @MockBean
    private ElasticsearchService elasticsearchService;

    @Autowired
    private ElasticRestController elasticRestController;

    @Autowired
    private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;

    @Autowired
    private MockMvc mockMvc;

    @Rule
    public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();

    @Before
    public void before() {
        mockMvc = MockMvcBuilders.standaloneSetup(elasticRestController)
                .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver())
                .setMessageConverters(mappingJackson2HttpMessageConverter)
                .apply(MockMvcRestDocumentation.documentationConfiguration(this.restDocumentation))
                .build();
    }

    @Test
    public void findLogsByParametersTest() throws Exception {

        String searchRequest = "{\n" +
                "\t            \"levels\": [\"INFO\"],\n" +
                "                    \"module\": \"test module\",\n" +
                "                    \"version\": \"version 1\",\n" +
                "                    \"thread\": \"test thread\",\n" +
                "                    \"requestId\": \"1\",\n" +
                "                    \"message\": \"test message 3\",\n" +
                "                    \"rangeFrom\": \"2018-02-26T07:02:50.000Z\",\n" +
                "                    \"rangeTo\": \"2018-03-05T07:02:50.000Z\",\n" +
                "                    \"node\": \"first node\",\n" +
                "                    \"system\": \"super system 1\",\n" +
                "                    \"header\": \"test\",\n" +
                "                    \"submodule\": \"test submodule\",\n" +
                "                    \"operation\": \"some operation\",\n" +
                "                    \"service\": \"some service\",\n" +
                "                    \"type\": \"some type\",\n" +
                "                    \"metricType\": \"duration\",\n" +
                "                    \"valueFrom\":400,\n" +
                "                    \"valueTo\":600\n" +
                "}";
        SearchResponse searchResponse = getSearchResponse();
        when(elasticUIService.findLogsByParameters(any(ESLogRequestDTO.class),
                any(Pageable.class)))
                .thenReturn(searchResponse);

        mockMvc.perform(post("/api/logs/search")
                .contentType(CONTENT_TYPE)
                .content(searchRequest)
                .accept(CONTENT_TYPE)
        )
                .andDo(document(CLASS_NAME_METHOD_NAME))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE));

    }

    public SearchResponse getSearchResponse() {
        SearchResponse searchResponse = new SearchResponse();
        return searchResponse;
    }
}

我不明白如何用一些数据模拟填充 SearchResponse。有人有这方面的经验吗?也许有一些方法可以用 searchRequest 之类的 json 数据填充它?

【问题讨论】:

标签: java spring-boot elasticsearch junit


【解决方案1】:

SearchResponse 只有readFrom(InputStream) 方法来设置字段。使用此方法创建真正的 SearchResponse 对象会非常复杂,因为您需要知道流内容的内部格式。

你应该做的是使用像 Mockito 这样的模拟库来创建一个 SearchResponse 类型的模拟对象,但你可以在测试准备中定义方法的内容,例如getHits​() 应该返回。

使用 Mockito 创建和覆盖模拟行为的示例代码:

import static org.mockito.Mockito.*;
// mock creation
List mockedList = mock(List.class);
// define method behavior
when(mockedList.get(0)).thenReturn("first");
// the following prints "first"
System.out.println(mockedList.get(0));

由于 ElasticSearch API 在您访问实际值之前会返回大量内部对象,因此您应该在使用 Mockito 时查看deep stubs,这样您就不必模拟每个级别的对象。

【讨论】:

    猜你喜欢
    • 2014-10-15
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多