Spring 带有@WebMvcTest-@MockBean服务的单元测试帖子返回null

Spring 带有@WebMvcTest-@MockBean服务的单元测试帖子返回null,spring,unit-testing,spring-boot,mocking,Spring,Unit Testing,Spring Boot,Mocking,我正在尝试对控制器进行单元测试,以保存品牌实体。在这个测试中,我创建了一个我希望返回的品牌,然后将JSON发布到控制器。最初,我依靠的是通过引用传递,因此我的控制器方法基本上是: @Override public ResponseEntity<MappingJacksonValue> save(@Valid @RequestBody Brand brand, BindingResult bindingResult) { validate(brand, null, binding

我正在尝试对控制器进行单元测试,以保存
品牌
实体。在这个测试中,我创建了一个我希望返回的
品牌
,然后将JSON发布到控制器。最初,我依靠的是
通过引用传递
,因此我的控制器方法基本上是:

@Override
public ResponseEntity<MappingJacksonValue> save(@Valid @RequestBody Brand brand, BindingResult bindingResult) {

  validate(brand, null, bindingResult);
  if (bindingResult.hasErrors()) {
      throw new InvalidRequestException("Invalid Brand", bindingResult);
  }

  this.brandService.save(brand); // pass by reference
  MappingJacksonValue mappingJacksonValue = jsonView(JSON_VIEWS.SUMMARY.value, brand);
  return new ResponseEntity<>(mappingJacksonValue, HttpStatus.CREATED);
}
然而,当我调试时,从模拟服务返回的品牌是空的。下面是我的测试

@RunWith(SpringRunner.class)
@WebMvcTest(BrandController.class)
public class BrandSimpleControllerTest {

  @Autowire
  private MockMvc mockMvc;

  @MockBean
  private BrandService brandService;

  @Test
  public void testSave() throws Exception {
    Brand brand = new Brand();
    brand.setId(1L);
    brand.setName("Test Brand");

    when(this.brandService.save(brand)).thenReturn(brand);

    this.mockMvc.perform(this.post("/api/brands")
      .content("{\"name\": \"Test Brand\"}"))
      .andExpect(jsonPath("$.id", is(1)))
      .andExpect(jsonPath("$.name", is("Test Brand")));
  }

}

有什么建议吗?

好的,问题解决了。问题是,您在服务调用中模拟的对象必须与传递到控制器中的对象相同,因此当模拟查看预期内容时,它会说“哦,您给了我这个,所以您想要那个”。下面是使其工作的修改代码:

Brand brand = new Brand();
brand.setId(1L);
brand.setName("Test Brand");
brand.setDateCreated(new LocalDateTime());
brand.setLastUpdated(new LocalDateTime());

// since all I'm passing into the controller is a brand name...
when(this.brandService.save(new Brand("Test Brand"))).thenReturn(brand);

因为那个问题,我昨晚差点把头发拔掉。我用了Mockito.any()。但我知道在某个时刻,我必须发送一个确切的请求对象。然后,只有我能期望一个确切的对象作为响应,这样我才能进行断言。在这种情况下,我会保留这个答案。你好@Gregg,你介意详细解释一下“相同”是什么意思吗?我在服务方法调用中传递了两个“相同”的对象(DTO)(1个在我的@Test中,1个在我的控制器中),它们具有相同的精确属性值,但我模拟服务调用(
MockBean
)的控制器测试(
@WebMvcTest
)不起作用。基本上,我在模拟
服务.method(someObjectDTO)
,在@Test中,我为这个方法返回true,如下所示:
给定(服务.method(someObjectDTO))。将返回(true),但当测试运行时,控制器中的相同方法返回false:-(Hello@Gregg,我通过使用,
given(service.method((someObjectDTO)any(Object.class)).willReturn(true);
。但我仍然不明白为什么这不起作用
given(service.method(someObjectDTO)).willReturn(true);
:-(
Brand brand = new Brand();
brand.setId(1L);
brand.setName("Test Brand");
brand.setDateCreated(new LocalDateTime());
brand.setLastUpdated(new LocalDateTime());

// since all I'm passing into the controller is a brand name...
when(this.brandService.save(new Brand("Test Brand"))).thenReturn(brand);