2015-07-21 16 views
0

我有一个简单的控制器,定义如下:单元测试:未能完全履行请求

@Controller 
@RequestMapping("/rest/tests") 
public class TestController { 

    @Autowired 
    private ITestService testService; 

    @RequestMapping(value="/{id}", method=RequestMethod.DELETE) 
    @ResponseStatus(value = HttpStatus.OK) 
    public void delete(@PathVariable Integer id) 
    { 
     Test test = testService.getById(id); 
     testService.delete(test); 
    } 
} 

我一直在努力,以测试delete方法,并且至今都没有成功。我写的测试也很简单。

public class MockmvcTest { 

    @InjectMocks 
    private TestController test; 

    private MockMvc mockMvc; 

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

    @Test 
    public void myTest() throws Exception { 
     this.mockMvc.perform(delete("/rest/tests/{id}", new Integer(4))) 
     .andExpect(status().isOk()  
    } 
} 

我已经测试了在Chrome中使用“高级休息客户端”扩展的方法,并且按预期工作。

通过工作我的意思是从数据库中删除给定id的实体。

当执行myTest()时,状态码仍为200,但该实体未从数据库中删除。

这种行为背后的原因是什么?

回答

0

您正在使用Mockito将模拟服务注入到您的TestController(特别是ITestService)中。根据定义,所有嘲笑在您指定它之前都没有任何行为,默认情况下,您执行的所有操作都不会执行任何操作或返回null。您可以很容易地确认,通过在TestController.delete方法内设置断点,在调试模式下执行测试并检查testtestService变量的值。

Mockito用于单元级别的测试,用您设置为以某种可验证方式运行的模拟代替SUT's合作者。一旦你在你的SUT上调用方法(在你的情况下,这是TestController),你可以断言它是否遵守它的合同。

这实际上是一个很大的禁忌,允许您的自动化测试修改数据库的实际实例。

+0

那么我检查'test'和'testService'的值,只有'test'的值为空,另一个不是。有什么办法可以删除那个数据库实例吗?如果不是,那么进行这种测试的目的是什么?它甚至可以为数据库中不存在的实体返回OK。 – user3764893

+0

你的进一步的问题是相当广泛的,并且已经在很多地方得到了回答,例如http://stackoverflow.com/q/3622455/1240557 – kryger

+0

'这实际上是一个很大的禁忌,允许你的自动化测试修改一个真实的数据库“。我在春季用'Junit'测试了服务,包括删除在内的所有操作都成功了。这是否意味着我们不能使用mockito删除数据库中的实体? – user3764893