2017-06-13 55 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资源。