2016-12-15 77 views
0

我試圖單元測試控制器來保存一個Brand實體。在這個測試中,我創建了一個Brand,我希望能夠找回,然後我將JSON發佈到控制器。本來,我是靠着pass-by-reference所以我的控制方法,基本上是做:我實際上並沒有使用返回Brand從服務單元測試POST @WebMvcTest - @MockBean服務返回null

@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); 
} 

注意。當我以這種方式進行測試時,我的測試失敗了,因爲控制器正在返回我傳入的JSON,並且由於該服務被嘲笑,控制器沒有返回我期望的品牌,即擁有ID。所以我改變了控制器要做到這一點:

brand = this.brandService.save(brand); 

然而,當我調試,從嘲笑服務返回的品牌爲空。以下是我的測試。

@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"))); 
    } 

} 

有什麼建議?

回答

0

好的,問題解決了。問題在於你在服務調用中嘲笑的對象必須與傳遞給控制器​​的對象相同,所以當模擬着眼於預期的時候,它會說「哦,你給了我這個,所以你想要的」。以下是修改後的代碼:

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);