2017-06-13 166 views
1

我是Mockito新手,對Spring Data Web Support有點問題。Mockito Spring數據Web支持

我在我的控制器中有以下功能。

@DeleteMapping("/") 
public MyObject delete(@RequestParam("id")MyObject object){ 
...do something 
} 

這裏發生的事情(在實際使用中)描述爲here

問題是,當我在我的unitTests中使用MockMvc和Mockito時,沒有數據庫,也沒有持久性存儲庫。我如何讓Spring使用mockRepository替換我選擇的MyObject實例在/?id=1中移交的id。

這是測試的樣子:

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; 
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.InjectMocks; 
import org.mockito.Mock; 
import org.mockito.MockitoAnnotations; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.web.servlet.MockMvc; 
import org.springframework.test.web.servlet.setup.MockMvcBuilders; 

import com.mine.OrgUnitController; 
import com.mine.OrgUnitService; 

@RunWith(SpringJUnit4ClassRunner.class) 
public class OrgUnitControllerTest2 { 
    private MockMvc mockMvc; 
    @Mock 
    SomeService someService; 
    @InjectMocks 
    MyController controller; 

    @Before 
    public void init() { 
     MockitoAnnotations.initMocks(this); 
     mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); 
    } 

    @Test 
    public void test_delete() throws Exception { 
     mockMvc.perform(delete("/?id=1")).andExpect(status().isOk()); 
    } 
} 

我真的很感激任何幫助。

+0

你使用Spring Boot嗎? –

+0

你可以添加你的單元測試的例子嗎? – alayor

+0

@alayor當然,我做到了。 –

回答

0

那麼解決的方法很簡單,我只花了2天。 ;) 爲了使SpringDataWebSupport工作春天使用org.springframework.data.repository.support.DomainClassConverter這是一個ConversionService。接下來要知道的是,MockMvc通過setConversionService()接受ConversionService。所以唯一要做的就是寫我自己的ConversionService,其實很簡單。我伸出DefaultFormattingConversionService這樣的:

public class MockSpringDataWebSupport extends DefaultFormattingConversionService { 
    /** 
    * @param converters {@link Converter Converters} that shall be added to this {@link ConversionService} 
    */ 
    @SafeVarargs 
    public MockSpringDataWebSupport(Converter<? extends Object, ? extends Object>... converters) { 
     for (Converter<? extends Object, ? extends Object> converter : converters) { 
      this.addConverter(converter); 
     } 
    } 
} 

thisway我可以移交適合我的測試需要的任何coustom轉換器。在這個特殊情況下,我用:

 mockMvc = MockMvcBuilders.standaloneSetup(controller) 
      .setConversionService(new MockSpringDataWebSupport(new Converter<String, MyObject>() { 
       @Override 
       public OrgUnit convert(String source) { 
        return new MyObject(); 
       } 
      })).build(); 

它的工作。

0

要返回給定ID的MyObject,可以使用when(…​.).thenReturn(…​.)。所以當你在SomeService中有一個方法來通過id來查找MyObject時,你可以存根並返回值。

// When the get method is called, it will return MyObject 
when(someService.get(id)).thenReturn(new MyObject()); 
+0

對不起,但你沒有得到它。 –

+0

在調用Controllermethod之前由Spring DI完成替換MyObject,它不使用'SomeService',而是使用'org.springframework.data.repository.CrudRepository'的實現,它將在真實世界的場景中找到類路徑,但我的MockMvc由於某種原因不使用它。 –

0

我認爲這將是對你更容易,如果你只是用Mockito代替Mockito + MockMvc

你可以做這樣的事情:

@RunWith(SpringJUnit4ClassRunner.class) 
public class OrgUnitControllerTest2 { 
    @Mock 
    SomeService someService; 
    @InjectMocks 
    MyController controller; 

    @Before 
    public void init() { 
     MockitoAnnotations.initMocks(this); 
    } 

    @Test 
    public void test_delete() throws Exception { 
     //given 
     given(someService.delete(1)).willReturn(true); //or successful response 

     //when 
     MyObject response = controller.delete(1); 

     //then 
     assertTrue(OK, response.getStatus()) 
    } 
} 
+0

這個工作,但它不測試,我想要它測試。測試的目的是驗證對'/?id = 1'的請求最終在調用controller.delete()時發生,而您的情況不再是測試的一部分。 –

0

你或許應該需要設置setCustomArgumentResolversMockMvc對象,像這樣:

@Before 
    public void init() { 
     MockitoAnnotations.initMocks(this); 
     mockMvc = MockMvcBuilders 
      .standaloneSetup(controller) 
      .setCustomArgumentResolvers(new HandlerMethodArgumentResolver(){...}) 
      .build(); 
    } 

你需要找出哪些類實現HandlerMethodArgumentResolver,然後使用上面的方法init()

你可以看看this資源。