使用Mockito测试Spring组件

我认为,能够对弹簧组件进行单元测试而无需使用临时测试配置加载完整的弹簧上下文,这是一个很大的优势,因为它干净,易于维护,编写速度更快,更改平滑。

实现此目标的一种方法是使用Mockito并告诉他用Mocks (或Spies)替换您要测试的类中的@Autowired组件。

这里举个例子。

我们有一个名为SalaryService的服务,它会根据传递的雇员ID来猜测是什么,从而计算出假设的净工资。 简单的概念。

协作者需要一项服务,第一个是EmployeeDAO,用于检索工资总额,第二个是TaxCalculator,用于根据工资总额应用一些税款。

package com.marco.springmockito;
import java.math.BigDecimal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SalaryService {private static final BigDecimal minimumSalary = new BigDecimal(20000);@Autowiredprivate EmployeeDAO employeeDAO;@Autowiredprivate TaxCalculator taxCalculator;public BigDecimal getNetSalary(long employeeId) {BigDecimal netSalary = null;BigDecimal grossSalary = employeeDAO.getAnnualSalary(employeeId);BigDecimal taxes = taxCalculator.calculateTaxes(grossSalary);if (taxedSalaryIsGreaterThanMinimumSalary(grossSalary)) {netSalary = grossSalary.subtract(taxes);} else {netSalary = grossSalary;}return netSalary;}private boolean taxedSalaryIsGreaterThanMinimumSalary(BigDecimal taxedSalary) {return taxedSalary.compareTo(minimumSalary) == 1;}
}

EmployeeDAO是一项经典服务,负责从持久性存储中检索信息,并且看起来或多或少都是这样。

package com.marco.springmockito;
import java.math.BigDecimal;
import org.springframework.stereotype.Component;
@Component
public class EmployeeDAO {public BigDecimal getAnnualSalary(long employeeId) {// conncetTODB// run select for employeeId;return new BigDecimal(70000);}
}

TaxCalculator将需要TaxDao来检索税收信息,然后它将进行某种无聊且冗长的计算以退还税收。

package com.marco.springmockito;
import java.math.BigDecimal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class TaxCalculator {@Autowiredprivate TaxDao taxDao;public BigDecimal calculateTaxes(BigDecimal salary) {BigDecimal result = salary.multiply(taxDao.getTaxPercentageForYear(2014));// some other weird calculation ....return result;}
}

现在,我们要对SalaryService类进行单元测试。 我们不应被DAO和任何种类的数据库设置所困扰。 在此UNIT测试中,我们不在乎TaxCalculator在做什么。

我们想要的是测试我们的SalaryService行为是否符合预期,并且能够正确使用其协作者的工作。

这就是我们如何使用Mockito做到这一点。 我们用@InjectMocks标记要测试的类,并用@Mock标记其所有协作者(如果需要真正的实现,则标记@Spy )。

最后,我们需要在开始测试之前告诉我们的Unit框架,以操作所需的Mockito注入,然后使用
MockitoAnnotations。 initMocks(this);。

在测试中,我们需要模拟预期的操作,以便我们可以集中精力在SalaryService中要测试的实际逻辑上。

package com.marco.springmockito;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.when;
import java.math.BigDecimal;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class SalaryServiceTest {private static final long UserId = 123l;@InjectMocksprivate SalaryService salaryService;@Mockprivate EmployeeDAO employeeDAO;@Mockprivate TaxCalculator taxCalculator;@Beforepublic void init() {MockitoAnnotations.initMocks(this);}@Testpublic void testMinimumSalary() {BigDecimal annualSalary = new BigDecimal(10000);when(employeeDAO.getAnnualSalary(UserId)).thenReturn(annualSalary);when(taxCalculator.calculateTaxes(annualSalary)).thenReturn(new BigDecimal(1000));BigDecimal actual = salaryService.getNetSalary(UserId);assertThat(actual.compareTo(new BigDecimal(10000)), is(0));}@Testpublic void testMaximumSalary() {BigDecimal annualSalary = new BigDecimal(80000);when(employeeDAO.getAnnualSalary(UserId)).thenReturn(annualSalary);when(taxCalculator.calculateTaxes(annualSalary)).thenReturn(new BigDecimal(8000));BigDecimal actual = salaryService.getNetSalary(UserId);assertThat(actual.compareTo(new BigDecimal(72000)), is(0));}
}

它既简单又高效,希望对其他人有用。

参考:从我们的JCG合作伙伴 Marco Castigliego的Mockito中测试Spring组件,位于“ 删除重复并修复不良名称”博客中。

翻译自: https://www.javacodegeeks.com/2014/01/testing-spring-components-with-mockito.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366117.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python数字转换_Python实现中文数字转换为阿拉伯数字的方法示例

本文实例讲述了Python实现中文数字转换为阿拉伯数字的方法。分享给大家供大家参考,具体如下: 一、需求 今天写了三千二百行代码。 今天写了3200行代码。 两行意思相同,只是表达方式不太能够,统一掉。 二、原理 数字的特征是 数字 …

LeetCode第14题:最长公共前缀

题目描述 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 示例 1: 输入: ["flower","flow","flight"] 输出: "fl" 示例 2: 输入: ["dog","racecar"…

臭名昭著的sun.misc.Unsafe解释

Java虚拟机的最大竞争对手可能是托管C#等语言的Microsoft CLR 。 CLR允许编写不安全的代码作为低级编程的入口,这在JVM上很难实现。 如果您需要Java中的此类高级功能,则可能会被迫使用JNI ,这需要您了解一些C并Swift导致代码紧密耦…

主从复制

五 主从复制 Replication(重要!!!!!!) 5.1、介绍 基于主库二进制日志实时恢复到备库。 5.2、原理 5.2.1 主从复制的前提 (1)两台或两台以上数据库实例 (2)主库…

手机号正则表达 php,php 手机号码正则表达试程序代码_PHP教程

代码如下function funcMtel($str)//手机号码正则表达试{return (preg_match(“/(?:13d{1}|15[03689])d{8}$/”,$str))?true:false;}测试18678785887返回为false原因分析,查看了发现上面正则只能验证以13,15开头的,自然18开头的是不可以用的修改后代码如…

python输出格式控制_Python3.x那些事儿:[50]多种多样的输出格式

目前有两种方式来格式化输出格式,第一种就是自己动手来进行字符串的操作,虽然麻烦,但是都能实现。第二种方式就是使用str.format()函数。 string模块包含了一个Template类,这个类提供了把值替换成字符串的方法。 python提供把任意…

暑假第十五测

题解: 第一题: 20%枚举长度和每个子串,O(len)判断,随机情况复杂度可过 40%同样枚举长度,然后两个指针卡出区间,O(1)[或O(26)//可能可过?]判断 50%既然知道了40%的做法那…

扩展Spring Batch –步骤分区

在之前的几篇文章中,我们已经讨论了如何启动和运行Spring Batch。 现在,我们将开始讨论可用于扩展Spring Batch的一些策略。 本文将重点介绍如何对步骤进行分区,以使该步骤具有多个线程,每个线程并行处理一块数据。 如果您有大量…

zabbix磁盘的自动发现与磁盘指标监控

由于最近项目上需要对服务器监控进行规范化监控,再磁盘这块有几种方式 1.如果每台设备的磁盘是一样的 比如都有vda,vdb两块磁盘那么可以采用 1.1 每台客户端写脚本,服务端每台设备去加上监控项(------最次的手段-------------) 1.…

[代码笔记]VUE路由根据返回状态判断添加响应拦截器

//返回状态判断(添加响应拦截器)Axios.interceptors.response.use(res > {//对响应数据做些事if (res.data && !res.data.success) {Message({// 饿了么的消息弹窗组件,类似toastshowClose: true,message: res.data.error.message.message? res.data.error.messag…

php前台用户权限开通,vue实现网站前台的权限管理

本文主要介绍了基于vue实现网站前台的权限管理(前后端分离实践),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。Javascript做为当下的热门语言,用途很广泛&#xff0c…

一种替代的多生产者方法

最近在InfoQ上,Aliasei Papou发表了一篇关于他的一些实验的文章 ,该实验在线程之间进行了高性能的消息交换。 本文中有许多示例,但我将重点介绍多生产者案例。 文章显示的一种优化方法是,如果您知道初始化时拥有的生产者数量&…

maven连接国内仓库

<mirrors> <!-- 阿里云仓库 --> <mirror> <id>alimaven</id> <mirrorOf>central</mirrorOf> <name>aliyun maven</name> <url>http://maven.aliyun.c…

python知识点汇总_Python知识点总结大全(一)

python逻辑运算符 1.成员 and or not 优先级&#xff1a;() > not > and > or 2.and 逻辑运算符and&#xff0c;a andb&#xff0c;如果a和b都为True&#xff0c;则返回True&#xff0c;如果其中一个为False&#xff0c;返回False&#xff0c;简言之&#xff1a;一假则…

JS ES6中的箭头函数(Arrow Functions)使用

转载这篇ES6的箭头函数方便自己查阅。 ES6可以使用“箭头”&#xff08;>&#xff09;定义函数&#xff0c;注意是函数&#xff0c;不要使用这种方式定义类&#xff08;构造器&#xff09;。 一、语法 基础语法 (参数1, 参数2, …, 参数N) > { 函数声明 }(参数1, 参数…

php中trim的用法和例子,PHP ltrim()用法及代码示例

ltrim()函数是PHP中的内置函数&#xff0c;可从字符串左侧删除空格或其他字符(如果指定)。用法:ltrim( $string, $charlist )参数&#xff1a;函数ltrim()接受两个参数&#xff0c;如上面的语法所示。在这两个参数中&#xff0c;一个是必需的&#xff0c;另一个是可选的。下面将…

python怎样编写定时程序_Python如何实现定时器功能

Timer: 隔一定时间调用一个函数,如果想实现每隔一段时间就调用一个函数的话&#xff0c;就要在Timer调用的函数中&#xff0c;再次设置Timer。Timer是Thread的一个派生类 python中的线程提供了java线程功能的子集。 #!/usr/bin/env python from threading import Timer import …

应用ForkJoin –从最佳到快速

到目前为止&#xff0c;JDK 7已很好地掌握在开发人员手中&#xff0c;并且大多数人都听说过ForkJoin&#xff0c;但是没有多少人有时间或机会去尝试它。 它引起了&#xff0c;并且可能仍然引起一些混乱&#xff0c;与普通线程池有什么不同。 [1] 我在本文中的目标是通过一个代…

Echarts-K线图提示框改头换面

工作&#xff1a; 使用Hbuilder建web工程&#xff0c;加入echarts相关库&#xff0c;根据需要更改K线图及其的提示样式&#xff0c;去除默认提示&#xff0c;使用异步加载echarts的数据&#xff0c;数据格式为json。 需要注意的K线图和5日均线&#xff0c;10日均线的意义&#…

JS对url进行编码和解码(三种方式区别)

Javascript语言用于编码的函数&#xff0c;一共有三个&#xff0c;最古老的一个就是escape()。虽然这个函数现在已经不提倡使用了&#xff0c;但是由于历史原因&#xff0c;很多地方还在使用它&#xff0c;所以有必要先从它讲起。 escape 和 unescape 实际上&#xff0c;esca…