使用 ObjectIds 使用 Spring, MongoDB 测试 REST 端点



我是MongoDB的新手,我正在为Mongo支持的REST Web服务编写一系列单元测试。下面是一个针对/clients/{id} 点的简单测试:

@RunWith(MockitoJUnitRunner.class)
public class ClientsControllerMockMvcStandaloneTest {
    private MockMvc mvc;
    @Mock
    private ClientsRepository clientsRepository;
    @Mock
    private ModelMapper modelMapper;
    @InjectMocks
    private ClientsController clientsController;
    private ExceptionHandlerExceptionResolver createExceptionResolver() {
        ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {
            @SuppressWarnings("ConstantConditions")
            @Override
            protected ServletInvocableHandlerMethod getExceptionHandlerMethod(final HandlerMethod handlerMethod,
                                                                              final Exception exception) {
                final Method method = new ExceptionHandlerMethodResolver(RestResponseEntityExceptionHandler.class)
                        .resolveMethod(exception);
                final RestResponseEntityExceptionHandler handler = new RestResponseEntityExceptionHandler();
                return new ServletInvocableHandlerMethod(handler, method);
            }
        };
        exceptionResolver.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
        exceptionResolver.afterPropertiesSet();
        return exceptionResolver;
    }
    @Before
    public void setup() {
        JacksonTester.initFields(this, new ObjectMapper());
        mvc = MockMvcBuilders.standaloneSetup(clientsController)
                .setHandlerExceptionResolvers(createExceptionResolver())
                .build();
    }
    // GET /api/clients/{id} 200
    @Test
    public void findById_ClientEntryFound_ShouldReturnFoundClientEntry() throws Exception {
        final ObjectId id = new ObjectId();
        final Client client = Client.builder()
                .id(id)
                .name("Microsoft")
                .build();
        final ClientDTO clientDTO = ClientDTO.builder()
                .id(id)
                .name("Microsoft")
                .build();
        when(clientsRepository.findById(id))
                .thenReturn(Optional.of(client));
        when(modelMapper.map(client, ClientDTO.class))
                .thenReturn(clientDTO);
        mvc.perform(get("/clients/" + id.toString())
                .accept(TestUtils.APPLICATION_JSON_UTF8))
                .andExpect(content().contentType(TestUtils.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.id", is(id)))
                .andExpect(jsonPath("$.name", is("Microsoft")))
                .andDo(MockMvcResultHandlers.print());
        verify(modelMapper, times(1)).map(client, ClientDTO.class);
        verify(clientsRepository, times(1)).findById(id);
        verifyNoMoreInteractions(clientsRepository);
    }
}

我希望这可以工作,但我得到以下内容:

java.lang.AssertionError: JSON path "$.id"
Expected: is <5c9b9a0289d2b311b150b92c>
     but: was <{timestamp=1553701378, machineIdentifier=9032371, processIdentifier=4529, counter=5290284, timeSecond=1553701378, time=1553701378000, date=1553701378000}>
Expected :is <5c9b9a0289d2b311b150b92c>
Actual   :<{timestamp=1553701378, machineIdentifier=9032371, processIdentifier=4529, counter=5290284, timeSecond=1553701378, time=1553701378000, date=1553701378000}>
 <Click to see difference>
任何

帮助将不胜感激(如果您认为我的一般方法可以改进,包括任何指示!

干杯!

Jackson 不知道您的 ObjectId 实例应该序列化为 5c9b9a0289d2b311b150b92c 而不是:

{
  "timestamp": 1553701378,
  "machineIdentifier": 9032371,
  "processIdentifier": 4529,
  "counter": 5290284,
  "time": 1553701378000,
  "date": 1553701378000,
  "timeSecond": 1553701378
}

幸运的是,它很容易修复。ObjectId#toString()方法(将在内部调用 ObjectId#toHexString()(允许您将ObjectId实例转换为 24 字节的十六进制字符串表示形式。

因此,您可以将@JsonSerializeToStringSerializer一起使用,将ObjectId实例表示为字符串:

@JsonSerialize(using = ToStringSerializer.class)
private ObjectId id;

然后,在测试中,使用 ObjectId#toString() 方法(或 ObjectId#toHexString() (进行断言:

.andExpect(jsonPath("$.id", is(id.toString())))

或者,假设您使用的是MongoDB的Spring Data,而不是ObjectId,您可以使用:

@Id
private String id;

您还可以在映射器图层中处理ObjectIdString的转换。

相关内容

  • 没有找到相关文章

最新更新