【问题标题】:MockMvc returns null instead of objectMockMvc 返回 null 而不是 object
【发布时间】:2017-04-11 10:55:03
【问题描述】:

我正在开发一个微服务应用程序,我需要测试一个发布请求 到控制器。手动进行测试,但测试用例总是返回 null。

我在 Stackoverflow 和文档中阅读了许多类似的问题,但还没有弄清楚我缺少什么。

这是我目前拥有的以及我为使其工作所做的尝试:

//Profile controller method need to be tested
@RequestMapping(path = "/", method = RequestMethod.POST)
public ResponseEntity<Profile> createProfile(@Valid @RequestBody User user, UriComponentsBuilder ucBuilder) {
    Profile createdProfile = profileService.create(user); // line that returns null in the test
    if (createdProfile == null) {
        System.out.println("Profile already exist");
        return new ResponseEntity<>(HttpStatus.CONFLICT);
    }
    HttpHeaders headers = new HttpHeaders();
    headers.setLocation(ucBuilder.path("/{name}").buildAndExpand(createdProfile.getName()).toUri());
    return new ResponseEntity<>(createdProfile , headers, HttpStatus.CREATED);
}

//ProfileService create function that returns null in the test case
public Profile create(User user) {
    Profile existing = repository.findByName(user.getUsername());
    Assert.isNull(existing, "profile already exists: " + user.getUsername());

    authClient.createUser(user); //Feign client request

    Profile profile = new Profile();
    profile.setName(user.getUsername());
    repository.save(profile);

    return profile;
}

// The test case
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ProfileApplication.class)
@WebAppConfiguration
public class ProfileControllerTest {

    @InjectMocks
    private ProfileController profileController;

    @Mock
    private ProfileService profileService;

    private MockMvc mockMvc;

    private static final ObjectMapper mapper = new ObjectMapper();

    private MediaType contentType = MediaType.APPLICATION_JSON;

    @Before
    public void setup() {
        initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(profileController).build();
    }
    @Test
    public void shouldCreateNewProfile() throws Exception {

        final User user = new User();
        user.setUsername("testuser");
        user.setPassword("password");

        String userJson = mapper.writeValueAsString(user);

        mockMvc.perform(post("/").contentType(contentType).content(userJson))
                .andExpect(jsonPath("$.username").value(user.getUsername()))
                .andExpect(status().isCreated());

    }
}

尝试在发布前添加when/thenReturn,但仍然返回带有空对象的409响应。

when(profileService.create(user)).thenReturn(profile);

【问题讨论】:

  • 正如错误所说,您已经在数据库中获得了用户详细信息
  • 测试用例使用内存数据库,通常在启动时没有任何条目。

标签: spring spring-mvc junit mockito microservices


【解决方案1】:

您在测试中使用了模拟 profileService,但您从未告诉该模拟要返回什么。所以它返回null。

你需要类似的东西

when(profileService.create(any(User.class)).thenReturn(new Profile(...));

注意使用

when(profileService.create(user).thenReturn(new Profile(...));

仅当您在 User 类中正确覆盖 equals()(和 hashCode())时才会起作用,因为控制器接收的实际 User 实例是您在测试中拥有的用户的序列化/反序列化副本,而不是同一个实例。

【讨论】:

  • any(User.class) 和 override equals()/hashCode() 都解决了我的问题。非常感谢。您认为哪一种更适合用于这种情况?
  • 我通常避免在实体中定义 equals() 和 hashCode()。这导致的问题多于解决的问题,而且很难为它们找到一个好的实现。所以我会在这里使用任何匹配器,或者其他匹配器。
猜你喜欢
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 2015-05-29
  • 1970-01-01
  • 2021-11-10
  • 1970-01-01
  • 2021-10-04
相关资源
最近更新 更多