如何对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: 148170623 * Date: 5/16/1724 * Time: 7:36 AM25 * To change this template use File | Settings | File Templates.26 */27 @RunWith(SpringJUnit4ClassRunner.class)28 @WebAppConfiguration29 @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 @Autowired35 private org.springframework.web.context.WebApplicationContext context;36 37 @Autowired38 private StaticController staticController;39 40 @Before41 public void before(){42 mockMvc = MockMvcBuilders.standaloneSetup(staticController).build();43 }44 45 @Test46 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: 148170624 * Date: 5/16/1725 * Time: 7:36 AM26 * To change this template use File | Settings | File Templates.27 */28 @RunWith(SpringJUnit4ClassRunner.class)29 @WebAppConfiguration30 @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 @Mock36 private FileTransferService fileTransferService;37 38 @Mock39 private JobSchedulerService jobSchedulerService;40 41 @Mock42 private HandleExceptionService handleExceptionService;43 44 @InjectMocks45 StaticController staticController;46 47 @Before48 public void setup(){49 MockitoAnnotations.initMocks(this);50 this.mockMvc = MockMvcBuilders.standaloneSetup(staticController).build();51 }52 53 @Test54 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 @Spy3 Foo spyOnFoo = new Foo();4 @Before5 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