如何对Spring及Spring MVC框架进行单元测试?
JUnit中提供了支持
主要分为三种那个方式:
1.直接对spring中注入的bean进行测试(以DAO为例)
这个可以用来测试除Controller之外的单元
1 package service; 2 import static org.Junit.Assert.assertEquals; 3 4 import org.Junit.Test; 5 import org.Junit.runner.RunWith; 6 import org.Springframework.beans.factory.annotation.Autowired; 7 import org.Springframework.test.context.ContextConfiguration; 8 import org.Springframework.test.context.Junit4.SpringJUnit4ClassRunner; 9 import org.Springframework.transaction.annotation.Transactional; 10 11 import domain.Account; 12 13 @RunWith(SpringJUnit4ClassRunner.class) 14 @ContextConfiguration("/config/Spring-db1.xml") 15 @Transactional 16 public class AccountServiceTest1 { 17 @Autowired 18 private AccountService service; 19 20 @Test 21 public void testGetAcccountById() { 22 Account acct = Account.getAccount(1, "user01", 18, "M"); 23 service.insertIfNotExist(acct); 24 Account acct2 = service.getAccountById(1); 25 assertEquals(acct,acct2); 26 } 27 }
推荐阅读博文
https://www.ibm.com/developerworks/cn/java/j-lo-springunitest/
2.对springMVC进行测试,使用Mock。
Mock有2种常用的方式:1. 使用Spring MVC自带的Mock;2.使用Mockito。
http://www.cnblogs.com/jiaoyiping/p/4251759.html 中使用了SpringMVC自带的Mock org.springframework.test.web.servlet.MockMvc 类,对SpringMVC进行测试。
该文中还介绍了另外一种基于 org.jboss.resteasy.core.Dispatcher类的测试方式。
该方法模拟发出HTTP请求,对Spring MVC进行测试。
1 package com.scb.jason.filetrans.controller; 2 3 import com.scb.jason.filetrans.service.FileTransferService; 4 import com.scb.jason.filetrans.service.HandleExceptionService; 5 import com.scb.jason.filetrans.service.JobSchedulerService; 6 import org.junit.Before; 7 import org.junit.Test; 8 import org.junit.runner.RunWith; 9 import org.springframework.beans.factory.annotation.Autowired; 10 import org.springframework.test.context.ContextConfiguration; 11 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 12 import org.springframework.test.context.web.WebAppConfiguration; 13 import org.springframework.test.web.servlet.MockMvc; 14 import org.springframework.test.web.servlet.ResultActions; 15 import org.springframework.test.web.servlet.setup.MockMvcBuilders; 16 17 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; 18 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 19 20 /** 21 * Created with IntelliJ IDEA. 22 * User: 1481706 23 * Date: 5/16/17 24 * Time: 7:36 AM 25 * To change this template use File | Settings | File Templates. 26 */ 27 @RunWith(SpringJUnit4ClassRunner.class) 28 @WebAppConfiguration 29 @ContextConfiguration(locations = {"classpath:beans.xml","file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml"}) 30 public class StaticControllerTest { 31 32 private MockMvc mockMvc; 33 34 @Autowired 35 private org.springframework.web.context.WebApplicationContext context; 36 37 @Autowired 38 private StaticController staticController; 39 40 @Before 41 public void before(){ 42 mockMvc = MockMvcBuilders.standaloneSetup(staticController).build(); 43 } 44 45 @Test 46 public void testFileTransfer(){ 47 System.out.println(); 48 try { 49 ResultActions actions = this.mockMvc.perform(get("/TestTransfer")); 50 System.out.println(status()); 51 System.out.println(content().toString()); 52 } catch (Exception e) { 53 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. 54 } 55 } 56 57 }
现在大多数推荐的方式是Mockito,在下一节中,我们会详细讨论Mockito。
1 package com.scb.jason.filetrans.controller; 2 3 import com.scb.jason.filetrans.service.FileTransferService; 4 import com.scb.jason.filetrans.service.HandleExceptionService; 5 import com.scb.jason.filetrans.service.JobSchedulerService; 6 import org.junit.Before; 7 import org.junit.Test; 8 import org.junit.runner.RunWith; 9 import org.mockito.InjectMocks; 10 import org.mockito.Mock; 11 import org.mockito.MockitoAnnotations; 12 import org.springframework.test.context.ContextConfiguration; 13 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 import org.springframework.test.context.web.WebAppConfiguration; 15 import org.springframework.test.web.servlet.MockMvc; 16 import org.springframework.test.web.servlet.ResultActions; 17 import org.springframework.test.web.servlet.setup.MockMvcBuilders; 18 19 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; 20 21 /** 22 * Created with IntelliJ IDEA. 23 * User: 1481706 24 * Date: 5/16/17 25 * Time: 7:36 AM 26 * To change this template use File | Settings | File Templates. 27 */ 28 @RunWith(SpringJUnit4ClassRunner.class) 29 @WebAppConfiguration 30 @ContextConfiguration(locations = {"classpath:beans.xml","file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml"}) 31 public class StaticControllerTest { 32 33 private MockMvc mockMvc; 34 35 @Mock 36 private FileTransferService fileTransferService; 37 38 @Mock 39 private JobSchedulerService jobSchedulerService; 40 41 @Mock 42 private HandleExceptionService handleExceptionService; 43 44 @InjectMocks 45 StaticController staticController; 46 47 @Before 48 public void setup(){ 49 MockitoAnnotations.initMocks(this); 50 this.mockMvc = MockMvcBuilders.standaloneSetup(staticController).build(); 51 } 52 53 @Test 54 public void testTestException() throws Exception { 55 ResultActions resultActions = mockMvc.perform(get("/TestException")); 56 } 57 }
这里还要着重讲一下,一个优秀的Mock工具Mockito。
http://blog.csdn.net/guijiaoba/article/details/51945873
http://blog.csdn.net/u010834071/article/details/47665791
推荐阅读,该博文详细介绍了Mockito的使用方法。
Mock的意思就是模拟出一个类对象,使其拥有类对象的全部接口。
我们可以通过when来规定mock对象调用时的值。
可以实现测试的解耦。比如说A依赖于B,C,那么我们就Mock B和C对象,将其注入到A。
并用When来模拟B和C对象的行为。这样就实现了在测试当中的解耦操作。
Mock中也存在部分Mock,即根据需求去选择调用Mock或者真实对象。
http://www.cnblogs.com/softidea/p/4204389.html介绍了如何实现部分Mock。
分为两种,一种是callRealMethod,一种是用Spy。
callRealMethod
1 //you can create partial mock with spy() method: 2 List list = spy(new LinkedList()); 3 //you can enable partial mock capabilities selectively on mocks: 4 Foo mock = mock(Foo.class); 5 //Be sure the real implementation is 'safe'. 6 //If real implementation throws exceptions or depends on specific state of the object then you're in trouble. 7 when(mock.someMethod()).thenCallRealMethod();
spy方式
1 public class Test{ 2 @Spy 3 Foo spyOnFoo = new Foo(); 4 @Before 5 public void init(){ 6 MockitoAnnotations.initMocks(this); 7 } 8 ... 9 }
这篇博文讲的不错,有兴趣的可以阅读一下。
http://qiuguo0205.iteye.com/blog/1443344
http://blog.csdn.net/u010834071/article/details/47665791
http://www.cnblogs.com/wade-xu/p/4311657.html
http://zhaozhiming.github.io/blog/2014/06/16/spring-mvc-unit-test-part-1/
http://blog.csdn.net/qbg19881206/article/details/17077021
http://www.cnblogs.com/wade-xu/p/4311657.html