基于Spring MVC做单元测试 —— 使用JMockit
来源:互联网 发布:ubuntu lts什么意思 编辑:程序博客网 时间:2024/06/05 09:29
转载地址:http://www.techv5.com/topic/696/
下面再介绍一下通过JMockit这个Java Mock工具来进行spring的单元测试,其特点是不需指定spring的配置文件,任何对象都可以mock出来并进行关联。
Controller
import com.odde.mail.model.Result;import com.odde.mail.service.MailService;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.codehaus.jackson.map.ObjectMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import static java.lang.String.format;@Controller@RequestMapping("/mail")public class MailController { private static final Log log = LogFactory.getLog(MailController.class); private final ObjectMapper mapper = new ObjectMapper(); @Autowired private MailService mailService; @RequestMapping(value = "/send", method = RequestMethod.POST, produces = "text/plain;charset=UTF-8") public @ResponseBody String send(@RequestParam("recipients") String recipients, @RequestParam("subject") String subject, @RequestParam("content") String content) throws Exception { log.debug("mail controller send start"); log.debug(format("recipients:%s", recipients)); log.debug(format("subject:%s", subject)); log.debug(format("content:%s", content)); Result mailResult = mailService.send(recipients, subject, content); String result = mapper.writeValueAsString(mailResult); log.debug(format("result:%s", result)); log.debug("mail controller send finish"); return result; }}
首先我们还是来看一下使用了JMockit的Controller单元测试是怎么写的,Controller的功能代码可见上面。
import com.odde.mail.model.Result;import com.odde.mail.service.MailService;import mockit.Expectations;import mockit.Injectable;import mockit.Tested;import mockit.integration.junit4.JMockit;import org.junit.Test;import org.junit.runner.RunWith;import static org.hamcrest.CoreMatchers.is;import static org.junit.Assert.assertThat;@RunWith(JMockit.class)public class MailControllerTest { @Tested MailController mailController; @Injectable private MailService mailService; @Test public void should_return_status_success_when_send_mail_success() throws Exception { new Expectations() { { mailService.send("test@test.com", "test", "test"); result = new Result("成功"); } }; String result = mailController.send("test@test.com", "test", "test"); assertThat(result, is("{\"status\":\"成功\"}")); }}
- @RunWith(JMockit.class): 指定单元测试的执行类为JMockit.class;
- @Tested: 这个Annotate是指被测试类,在这个测试案例中我们要测试的是MailController,所以我们给其打上这个标签;
- @Injectable: 这个Annotate可以将对象进行mock并自动关联到被测试类,而不需要通过其他文件类似spring的配置文件等来进行关联;
- @Expectations: mock对象mailService的send方法,让其返回一个Result对象;
Service
再来看一下Service的单元测试要怎么改写,同样Service的功能代码可以看上一篇Post。
import com.odde.mail.model.Recipient;import com.odde.mail.model.Result;import com.odde.mail.repo.RecipientRepository;import mockit.Injectable;import mockit.NonStrictExpectations;import mockit.Tested;import mockit.integration.junit4.JMockit;import org.junit.Test;import org.junit.runner.RunWith;import java.util.List;import static java.util.Arrays.asList;import static org.hamcrest.core.Is.is;import static org.junit.Assert.assertThat;@RunWith(JMockit.class)public class RecipientServiceTest { @Tested private RecipientService recipientService; @Injectable private RecipientRepository recipientRepository; @Test public void should_return_success_when_add_recipient_not_exist() throws Exception { Result result = recipientService.add("Tom", "test@test.com"); assertThat(result.getStatus(), is("成功")); }}
相对Controller Test这里少了一步对recipientRepository对象findByEmail方法的mock,因为如果不通过Expectations进行方法mock的话,方法会默认返回null,而我们要测试的场景正是需要findByEmail方法返回null,所以mock方法这一步我们也省了。改写后的整体代码也比原来的少了很多,而且速度更快。
适当使用Mock框架
JMockit功能非常强大,不仅可以轻松处理上面的这些测试场景,还可以对static,final,private等方法进行mock,可以让你的单元测试毫无阻碍的进行。
但是如果过度的使用Mock框架,会让功能代码的坏味道被掩盖。本来单元测试的设计可以让你发现功能代码上的一些设计是否合理,比如有没有紧耦合等,但使用JMockit可以让你在设计不合理的代码上也可以轻松地进行单元测试,这样你就很难发现功能代码上的问题了。
所以建议JMockit等类似的mock框架还是要谨慎使用,首先要保证功能代码设计合理,满足面向对象设计的要求,再来考虑提高单元测试效率的问题。
http://zhaozhiming.github.io/blog/2014/06/17/spring-mvc-unit-test-part-2/
- 基于Spring MVC做单元测试 —— 使用JMockit
- java使用jUnit,jMockit,dbunit做DAO层单元测试方法
- 基于Spring MVC(REST API)做单元测试(mockito)
- 基于Spring MVC(REST API)做单元测试(mockito)
- 单元测试mock框架——jmockit实战
- 单元测试mock框架——jmockit实战
- 单元测试mock框架——jmockit实战
- 使用JMockit编写java单元测试
- 使用JMockit编写java单元测试
- 使用Junit4和JMockit进行单元测试
- Controller 使用RestTemplate进行单元测试 spring mvc
- Spring中如何使用Mockito做单元测试
- 基于Java spring MVC框架 开发初步 ——以做一个留言板为例
- Spring MVC学习-----------对Action做JUnit单元测试
- 单元测试中mock的使用及mock神器jmockit实践
- 单元测试中mock的使用及mock神器jmockit实践
- 单元测试-JMockit中使用参数化(多参数)测试
- 用JMockit写单元测试
- iOSlabel
- Android Material Design系列之RecyclerView和CardView
- Java中String的用法
- 2016全球大数据战略版图剖析(8):数据资源/API篇
- laravel框架学习之数据库相关操作(三)
- 基于Spring MVC做单元测试 —— 使用JMockit
- java selflearning
- poj2421【MST-prim+Kruskal】
- bootstrap后台框架源码 java图片爬虫 自定义表单
- Android之TelephonyManager
- 各Json技术比较
- linux 在使用ssh实现内网互联互通时候提示connected by ip 错误的解决方法
- 集成支付宝支付 报错 解决方法
- oracle表分区详解