junit使用mock objects进行单元测试

Junit学习(二):不同的测试策略 测试覆盖率 测试覆盖率工具可以告诉哪些代码被测试覆盖了,哪些没有被测试到。理想状态下,应该是百分之百的代码覆盖率,这样我们才能确认自己的代码逻辑功能没有因为重构而破坏。通常IDE会提供相应的功能或者插件来提供测试覆盖率的检测功能,笔者使用的是IDEA开发工具,启用和设置测试覆盖率工具的方法见以下链接: https://www.w3cschool.cn/intellij_idea_doc/intel... 阅读详情

上一篇我介绍了使用stub进行单元测试。那么mock objects和stub有何区别?什么情况下使用mock objects呢?

下面摘自junit in action书中的解释:

mock objects (或者简称为 mocks),非常适用于将某一部分代码与其他代问隔离开来,并对这部分代码进行测试。

mocks 替换了测试中与你的方法协作的对象,从而提供个隔离层。从这一点来讲,它与 stub 有些类似。不过相似之处也仅限于

此,因为mocks 并不实现任何逻辑 它们只是提供了一种使测试能够控制仿造类的所有业务逻辑方法行为的方法的空壳。

 

下面以一个账户转账的测试用例加以说明。大家可以比较下其与stub的区别。

 

创建账户类

package com.lhy.junitkaifa.mocks.account;

/**
 * 账户
 *
 * @author xusucheng
 * @create 2018-12-22
 **/
public class Account {
    private String accountId;
    private long balance;

    public Account(String accountId, long balance){
        this.accountId = accountId;
        this.balance = balance;
    }

    public void debit(long amount){
        this.balance-=amount;
    }

    public void credit(long amount){
        this.balance+=amount;
    }

    public long getBalance(){
        return this.balance;
    }
}

创建配置接口与实现

package com.lhy.junitkaifa.mocks.configurations;

/**
 * 配置
 *
 * @author xusucheng
 * @create 2018-12-22
 **/
public interface Configuration {
    String getSQL(String sqlString);
}
package com.lhy.junitkaifa.mocks.configurations;

/**
 * @author xusucheng
 * @create 2018-12-22
 **/
public class DefaultConfiguration implements Configuration {
    public DefaultConfiguration(String configuration){

    }

    @Override
    public String getSQL(String sqlString) {
        return null;
    }
}

 

创建账户管理接口与实现

package com.lhy.junitkaifa.mocks.account;

/**
 * 账户管理接口
 *
 * @author xusucheng
 * @create 2018-12-22
 **/
public interface AccountManager {
    Account findAccountById(String userId);

    void updateAccount(Account account);
}
package com.lhy.junitkaifa.mocks.account;

import com.lhy.junitkaifa.mocks.configurations.Configuration;
import com.lhy.junitkaifa.mocks.configurations.DefaultConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 账户管理接口实现
 *
 * @author xusucheng
 * @create 2018-12-22
 **/
public class AccountManagerImpl implements AccountManager {
    private Log logger;

    private Configuration configuration;

    public AccountManagerImpl(){
        this(LogFactory.getLog(AccountManagerImpl.class),new DefaultConfiguration("technical"));
    }

    public AccountManagerImpl(Log logger, Configuration configuration){
        this.logger = logger;
        this.configuration = configuration;
    }

    @Override
    public Account findAccountById(String userId) {
        this.logger.debug("Getting account for user["+userId+"]");
        this.configuration.getSQL("FIND_ACCOUNT_BY_ID");

        return null;
    }

    @Override
    public void updateAccount(Account account) {
        //Do nothing.
    }


}

 

创建账户管理服务类

 

package com.lhy.junitkaifa.mocks.account;

/**
 * 账户管理服务
 *
 * @author xusucheng
 * @create 2018-12-22
 **/
public class AccountService {
    private AccountManager accountManager;

    /**
     * 注入具体实现
     * @param accountManager
     */
    public void setAccountManager(AccountManager accountManager){
        this.accountManager = accountManager;
    }

    public void transfer(String fromId, String toId, long amount){
        //转出账户
        Account from = this.accountManager.findAccountById(fromId);
        //转入账户
        Account to = this.accountManager.findAccountById(toId);
        from.debit(amount);
        to.credit(amount);
        this.accountManager.updateAccount(from);
        this.accountManager.updateAccount(to);
    }
}

 

创建测试用账户管理接口

package com.lhy.junitkaifa.mocks.account;

import java.util.HashMap;
import java.util.Map;

/**
 * @author xusucheng
 * @create 2018-12-22
 **/
public class MockAccountManager implements AccountManager{
    //保存所有账户
    private Map<String,Account> accounts = new HashMap<>();


    /**
     * 添加账户
     * @param userId
     * @param account
     */
    public void addAccount(String userId, Account account){
        this.accounts.put(userId,account);
    }


    /**
     * 获取账户
     * @param userId
     * @return
     */
    @Override
    public Account findAccountById(String userId) {
        return this.accounts.get(userId);
    }

    @Override
    public void updateAccount(Account account) {
        //不干事
    }
}

创建测试用日志类

package com.lhy.junitkaifa.mocks.account;

import org.apache.commons.logging.Log;

/**
 * @author xusucheng
 * @create 2018-12-22
 **/
public class MockLog implements Log {
    @Override
    public boolean isFatalEnabled() {
        return false;
    }

    @Override
    public boolean isErrorEnabled() {
        return false;
    }

    @Override
    public boolean isWarnEnabled() {
        return false;
    }

    @Override
    public boolean isInfoEnabled() {
        return false;
    }

    @Override
    public boolean isDebugEnabled() {
        return false;
    }

    @Override
    public boolean isTraceEnabled() {
        return false;
    }

    @Override
    public void fatal(Object o) {

    }

    @Override
    public void fatal(Object o, Throwable throwable) {

    }

    @Override
    public void error(Object o) {

    }

    @Override
    public void error(Object o, Throwable throwable) {

    }

    @Override
    public void warn(Object o) {

    }

    @Override
    public void warn(Object o, Throwable throwable) {

    }

    @Override
    public void info(Object o) {

    }

    @Override
    public void info(Object o, Throwable throwable) {

    }

    @Override
    public void debug(Object o) {

    }

    @Override
    public void debug(Object o, Throwable throwable) {

    }

    @Override
    public void trace(Object o) {

    }

    @Override
    public void trace(Object o, Throwable throwable) {

    }
}

 

创建测试用配置类

package com.lhy.junitkaifa.mocks.configurations;

/**
 * @author xusucheng
 * @create 2018-12-22
 **/
public class MockConfiguration implements Configuration {
    public void setSQL(String sqlString){

    }

    @Override
    public String getSQL(String sqlString) {
        return null;
    }
}

 

创建测试类

package com.lhy.junitkaifa.mocks.account;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

/**
 * @author xusucheng
 * @create 2018-12-22
 **/
public class TestAccountService {
    @Test
    public void testTransferOk(){
        MockAccountManager mockAccountManager = new MockAccountManager();
        Account from = new Account("1",200);
        Account to = new Account("2",100);
        mockAccountManager.addAccount("1", from);
        mockAccountManager.addAccount("2", to);

        AccountService accountService = new AccountService();
        accountService.setAccountManager(mockAccountManager);
        accountService.transfer("1","2",50);

        assertEquals(150,from.getBalance());
        assertEquals(150,to.getBalance());
    }
}

 

运行测试

 

 

 

 

Junit实战学习笔记 理解单元测试框架 1.每个单元测试都必须独立于其他所有单元测试而运行; 2.框架应该以单个测试未单位来检测和报告错误; 3.应该易于定义要运行哪些单元测试。 fixtures @Before  @After @BeforeClass  @AfterClass @Test @Ignore Junit断言方法 1. assertArrayEquals("mess 阅读详情

相关推荐

Mock技术实战:C++与Java单元测试中的依赖隔离与行为验证

在软件工程实践中,单元测试是确保代码质量的关键环节,而Mock技术则是实现高效单元测试的核心手段。其原理是通过创建虚拟对象来模拟真实的外部依赖,如数据库、网络服务等,从而将被测代码与复杂、不稳定的外部环境隔离。这项技术的核心价值在于提升测试的稳定性、执行速度,并能轻松模拟各种异常场景。从应用场景来看,Mock技术广泛应用于微服务架构、第三方API集成、数据访问层测试等需要控制依赖行为的领域。本文聚焦于Mock技术的具体实现,深入解析了在C++和Java两种主流语言中如何应用Mockito和Google Mo

weixin_30564785的博客 406

使用模拟对象(Mock Object)技术进行测试驱动开发

敏捷开发敏捷软件开发又称敏捷开发,是一种从上世纪 90 年代开始引起开发人员注意的新型软件开发方法。和传统瀑布式开发方法对比,敏捷开发强调的是在几周或者几个月很短的时间周期,完成相对较小功能,并交付使用。在项目周期内不断改善和增强。2001 年初,在美国犹他州雪鸟滑雪胜地,17 名编程大师分别代表极限编程、Scrum、特征驱动开发、动态系统开发方法、自适应软件开发、水晶方法、实用编程等开发

425

ZYNQ裸机双网口通信实战:手把手教你用SDK和LWIP配置PS+PL以太网(附完整源码)

本文详细介绍了在ZYNQ裸机环境下实现双网口通信的全流程,包括硬件配置、LWIP协议栈优化及TCP通信实现。通过Vivado SDK和LWIP协议栈,开发者可以高效配置PS端内置网口与PL端扩展网口,提升嵌入式网络应用的灵活性和性能。附完整源码,助力快速开发。

weixin_30831529的博客 424

认识Mock Object(转)

What is Mock Object?   在讨论中我大致了解到Mock Object一般是用来做辅助单元测试,它负责隔离Tested Object与真实环境中模块或实体(Real world object)的交互,并“替代”or “冒充”这些真实模块或实体与Tested Object进行交互。 在“JUnit in action”这本书中关于Mock Object的描述如下: A mock ...

walkes 306

tiny4412用 usb 连接计算机显示sec s5pc210 test b/d 解决方法

当我用USB线连接tiny4412的microUSB端口的时候,出现了驱动没有正常安装,显示“sec s5pc210 test b/d” 出现这种问题的原因有: 1、没有安装到正确的USB驱动; 2、SD卡没有插好 我出现问题的原因属于第二种,插入SD卡后,上电后,LCD屏亮了,但没有任何显示   解决方法是:     更换一张SD卡,重新插入开发板卡槽,上电开

karaskass的博客 3232

Intel SGX Explained

计算机中最主要的资源是CPU和内存,由操作系统和虚拟管理系统等系统软件来管理这些资源。

hanqdi_的博客 3456

使用Mock Object测试界面

       在编写Swing界面的时候,发现运用Mock Object可以很容易的实现界面的测试。在编写程序的时候,很多依赖外部的地方都要留个后门,不能硬写在程序里面,有的是做成setter,getter ,有的是将外部依赖提炼到一个方法中,在测试的时候,由子类来override。在实际编程中,使用的工具是Easy Mock,它是一个动态构建Mock Object的开软API,使用它,能够很方便

moneyice的专栏 1955

python爬取巨潮资讯网所有股票年报数据

爬虫获取巨潮资讯网数据

qq_42752524的博客 6117

Mock Object 入门

首先是:Mock FAQ 这个FAQ 可以解答大部分关于mock的问题,当然也是入门级的读物了。  接下来就是 jmock网站上的一系列的 tutorial了 http://www.jmock.org/docs.html#tutorials 保证自己会用Jmock的API 当然懂了API 不代表就掌握了mock接下来就深入一点吧,个人觉得mock object的第一篇文章 是必读的

camel0564的专栏 935

OpenHarmony Stage模型深度解剖:从Ability Kit到沙箱隔离的全链路底层原理

基于微内核架构,提供进程管理、内存管理、IPC通信等基础能力:包含V8引擎、ArkTS运行时、渲染引擎等核心组件:Ability Kit框架,提供应用生命周期管理、组件调度等能力:基于Stage模型的应用程序。

m0_67505153的博客 191

PyTorch实战(4)——卷积神经网络(Convolutional Neural Network,CNN)

卷积神经网络 (Convolutional Neural Network, CNN) 是一种广泛应用的深度学习模型。通过参数共享、局部感知和空间结构等优势,能够更好地处理图像数据,并在图像识别、目标检测和图像生成等任务中展现出强大的能力。在本节中,介绍了卷积的计算方法以及卷积神经网络的基本组件,并使用 PyTorch 构建了卷积神经网络以深入了解其工作原理。

盼小辉丶的博客 1万+

Mock Object技术与应用(七)

Mock Object技术与应用

m0_67519714的博客 331

功能安全实战系列07-英飞凌TC3xx电源监控开发详解

本文对电源监控(PBIST及MONBIST)开发介绍,步骤详细配合开发中的测试情况,图文并茂,方便理解。

initiallizer的博客 1109

Pragmatic Unit Testing in Java with JUnit 书评

书评 Pragmatic Unit Testing in Java with JUnit 看这本书时候正好在做一个java的项目,正好可以把书中的内容应用到项目中。这本书的作者是Andy Hunt和Dave Thomas。名著《The Pragmatic Programmer》正是出自他们之手。这本《pragmatic unit testing in java with junit》是The

climberY的专栏 1045

大数据学习指南从入门到精通

利用框架的力量,看懂游戏规则,才是入行的前提大多数人不懂,不会,不做,才是你的机会,你得行动,不能畏首畏尾选择才是拉差距关键,风向,比你流的汗水重要一万倍,逆风划船要累死人的为什么选择学习大数据开发,不选择Java开发?借棋弈做比喻,智商高的不要选择五子琪,要选择围棋,它能长久地吸引你。不都是在棋盘上一颗黑子一颗白子地下吗?因为围棋更复杂,能够掌握如此复杂的技艺、产生稳定输出的棋手、让我们更佩服。选择学习大数据开发也如此,能让你的职业生涯走得更远,少走弯路。

Lansonli(蓝深李)的博客 2万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

juint测试之类工厂重构 mock objects测试

使用mock objects进行测试,应用控制反转(Ioc)模式替换一个HTTP连接测试代码 代码:ConnectionFactory.java [...] import java.io.InputStream; public interface ConnectionFactory{ InputStream getInputStream() throws Exception; }

wuDaSong_的专栏 1352

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Junit3.8.1

学习笔记:深入的思索艰难的编码简单手动测试成功------喜悦-----止步Automate our task.测试的是代码不是测试人。java -cp junit.jar;. junit.swingui.TestRunner junit.samples.AllTestsjava -cp junit.jar;. junit.textui.TestRunner junit.samples.All

持续改进 1272

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

JUnit学习笔记7---mock objects进行孤立测试1

The secret of success is sincerity.once you can fake that  you have you have got it made.         ——Jean Giraudoux        本站内容:                  介绍并展示mock objects                 执行不同的重构

pan-zy的专栏 907

Java单元测试实战指南:从JUnit 5到Mockito的最佳实践

单元测试是软件工程中保障代码质量的核心实践,它通过隔离测试最小可执行单元,为开发者提供快速反馈。其核心原理在于通过Mock等技术模拟外部依赖,确保测试的独立性与执行效率,从而成为持续集成和敏捷开发流程的基石。在Java生态中,JUnit 5、Mockito和AssertJ构成了主流的测试工具链,它们共同支撑了测试驱动开发与重构安全网的技术价值。无论是Spring Boot服务、数据库交互层还是包含外部API调用的模块,遵循Given-When-Then模式与合理的测试分层策略,都能有效提升代码的健壮性与可维

weixin_30684743的博客 440

JUnit关于数据库访问的单元测试 (2)

对数据库访问的单元测试--------数据库访问代码用一套持久化API访问你的数据库.这类测试的目标是验证你是否正确使用了持久化API.测试策略主要是采用mock objects来模拟持久化API在不与数据库连接并且不在容器内的情况下运行测试. 现在我们来测试数据库访问代码.JDBC,JDO等等本身设计得很好,并且使用java接口,这样一来就非常适宜于mock objects策略.对于

leoshang的专栏 1740

转 JUnit关于数据库访问的单元测试 1

以下是对数据库进行单元测试的一个例子.      这是一个web程序,servlet从request里提取SQL语句,然后从DB里取得数据返回给JSP.     首先,假设你的数据库访问代码与业务逻辑代码已经清晰地区分开来.那么我们就可以对数据库访问进行不同的单元测试.     1.对业务逻辑的单元测试--------这些测试的目标是将业务逻辑代码部分与数据库访问代码部分(持久化代码JDBC/JD

leoshang的专栏 925

junit---用mock object进行隔离测试(下)

mock objects的使用范围     实际的对象有不确定的行为。     实际对象很难建立     实际对象有很难才能产生的行为(比如一个网络错误)     实际对象很迟钝。     实际对象有一个或者是一个UI总结:   这一章描述了一个叫mock objects的技术,他可以让我们从其他域对象或者环境中隔离出来进行单元测试。当写一个好的单元测试的时候,最大的障碍就是把自己从执行环境中抽象

huabingl的专栏 1975

JUnit 5单元测试实战:从核心注解到Mockito与Spring Boot集成

单元测试是保障软件质量与可维护性的基石,其核心在于通过隔离测试验证代码单元的行为是否符合预期。在Java生态中,JUnit作为事实标准的测试框架,结合Mockito等工具,能够有效模拟外部依赖,实现真正的单元隔离测试。这不仅提升了代码的可靠性,更通过测试驱动开发(TDD)推动产生松耦合、高内聚的软件设计,对于构建可持续交付的微服务或复杂业务系统至关重要。本文聚焦于JUnit 5的核心实战,通过构建一个完整的用户服务(UserService)示例,系统讲解如何运用@ParameterizedTest进行参数化

weixin_30947043的博客 331

JUnit4集成随机值工具:提升单元测试覆盖与代码健壮性实践

单元测试是保障软件质量的重要手段,但传统基于固定数据的测试往往难以覆盖真实场景中的复杂输入组合。通过引入随机数据生成机制,测试可以从确定性验证转向更全面的属性验证,有效提升代码的健壮性。其核心原理在于利用可控的随机源(如固定种子的Random类)生成多样化测试数据,模拟用户可能输入的各种边界和异常情况。这种技术价值在于能自动发现手动难以构造的边缘案例,暴露潜在的NullPointerException、数值溢出等隐蔽缺陷。在工程实践中,可结合Apache Commons Lang等工具库快速生成字符串、数字

weixin_30432579的博客 463

Java单元测试实战:JUnit5与Mockito集成指南与最佳实践

单元测试是保障软件质量的核心实践,通过隔离被测代码与外部依赖,确保逻辑正确性。其原理在于创建可控的测试环境,用模拟对象替代真实依赖,从而聚焦核心功能验证。这一技术价值在于提升测试速度、稳定性和可重复性,是持续集成和敏捷开发的重要支撑。在Java后端开发中,JUnit5作为主流测试框架,与Mockito模拟库的集成构成了高效测试的黄金组合。应用场景广泛覆盖服务层业务逻辑、数据访问层隔离以及外部API调用模拟等。本文以JUnit5和Mockito为核心,详解如何通过模拟对象解决数据库连接、外部服务调用等依赖问题

weixin_30608503的博客 391
上一篇: junit使用stub进行单元测试
下一篇: 超简单JSP人员信息管理系统(适合新手练手用)
罗汉爷
罗汉爷 新星创作者: Java技术领域 新星创作者: Java技术领域 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄14年 4912粉丝 605原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值