Mockito使用方法(Kotlin)

打印 上一主题 下一主题

主题 980|帖子 980|积分 2940

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、为什么要使用Mockito

1.实际案例

1.1 遇到的问题

对于经常维护的项目,经常遇到一个实际问题:需求不停改变,导致架构经常需要修改某些概念的定义。
对于某些十分基础又十分常用的概念,常常牵一发而动全身。
此时,"重构-测试"循环将会消耗比较多的费用。
1.2 解决方法1

可以通过领域驱动开发,在设计架构之前和相关领域的专家充分沟通,从而从一开始就得到准确的定义。
同时,在开发过程中对于之后有可能增加新功能的模块,充分增加其可拓展性。
1.2 解决方法2

通过编写高质量代码,保证单一功能由单一函数负责,从而减少增加新功能时的工作量。
1.3 根本原因

不论架构怎样设计,对于一个经常维护、更新的项目,其必然会在某些时刻遇到修改基本定义的情况。
而这些基本定义的大量引用,对于一名普通开发者来说,不一定能完全照顾到。
即使照顾到了,也不能保证下一次也同样不出问题。
1.4 解决方法3

使用自动化测试,在增加代码后用计算机代替人进行功能测试,从而大大提高测试效率。
在引入单元测试后,不仅能测试出“是否有问题”,更能高效找到错误出现的位置,效率显著高于传统的控制台输出调试方法。
2.行为驱动开发

2.1 概览

BDD:行为驱动开发
第一步:编写一个失败的"客户验收测试",从客户视角描述系统。
第二步:写系统代码,直到验收测试通过。
2.2 缺点

代码量大,前期成本高。
即该方法不适合一次性写完,之后几乎不维护的小型程序。
2.3 优点

后期开发效率大大提高。
因此,该方法适用于时常维护,使用时间很长的大型程序。
二、部署Mockito

1.gradle部署

build.gradle.kts
  1. dependencies {
  2.     testImplementation("org.mockito:mockito-core:4.3.1")
  3.     testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
  4.     testImplementation("org.mockito:mockito-inline:4.3.1")
  5.     testImplementation(fileTree("testLibs"))
  6.     testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
  7. }
复制代码
注意:testLibs可以改成任意文件夹名,这个文件夹放入你的外部依赖(如spigot的jar)
2.在哪里写测试代码

  1. import org.junit.jupiter.api.Test;
  2. public class TestStarter {
  3.     @Test
  4.     public void test(){
  5.         TestCore.INSTANCE.test();
  6.     }
  7. }
复制代码
3.ClassFormatError

这是因为你看起来导入了API,实际上没有导入好。
解决方法:把API(如Spigot)的jar文件放入testLibs(或你自己的文件夹名)
SpigotAPI下载地址:https://hub.spigotmc.org/nexus/content/repositories/snapshots/org/spigotmc/spigot-api/
4.ClassNotFoundError

这是因为你没有导入API。
解决方法:testImplementation("你需要的依赖"),示例如下
  1.     testImplementation("io.izzel.taboolib:common:6.0.10-11")
  2.     testImplementation("io.izzel.taboolib:module-configuration:6.0.10-11")
复制代码
三、使用方法

1.mock

用来创建一个虚假的对象,如Player。
  1. val player= Mockito.mock(Player::class.java)
复制代码
这个对象的类型就是Player,可以传递给别的方法,并且可以自定义触发player的方法时,执行和返回的内容。
2.when ... then ...

2.1 when ... thenReturn ...
  1. val player=mock(Player::class.java)
  2. `when`(player.name).thenReturn(playerName)
复制代码
  1. val playerLocation= mock(Location::class.java)
  2. `when`(playerLocation.x).thenReturn(0.0)
  3. `when`(playerLocation.y).thenReturn(0.0)
  4. `when`(playerLocation.z).thenReturn(0.0)
复制代码
这个方法可以用来指定返回值。
2.2 anyString()

对于有参数的方法,可以设定不论传入什么参数,都return特定值。
anyInt()等同理。
  1. val map= Mockito.mock(ConfigFile::class.java)
  2. Mockito.`when`(map.getString(anyString())).thenReturn("Test")
复制代码
2.3.thenAnswer

有时候,我们设置了anyString()之后,想使用实际传入的参数,就需要thenAnswer()。
arguments即为传入的实际参数。
  1. Mockito.`when`(map.getString(anyString())).thenAnswer { invocation ->
  2.             val args = invocation.arguments
  3.             var str = args[0] as String
  4.             fakeMap.getString(str)
  5.         }
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万万哇

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表