当前位置: 首页 > news >正文

web网站开发怎样使用模板国际购物网站平台有哪些

web网站开发怎样使用模板,国际购物网站平台有哪些,wordpress更换端口,哈尔滨seo优化团队目录 一、简介1.1 单元测试的特点1.2 Mock类框架的使用场景1.3 常见的Mock框架1.3.1 Mockito1.3.2 EasyMock1.3.3 PowerMock1.3.4 Testable1.3.5 比较 二、Mockito的使用2.1 导入pom文件2.2 mock对象和spy对象2.3 初始化mock/spy对象的方式2.4 参数匹配2.5 方法插桩2.6 InjectM…

目录

  • 一、简介
    • 1.1 单元测试的特点
    • 1.2 Mock类框架的使用场景
    • 1.3 常见的Mock框架
      • 1.3.1 Mockito
      • 1.3.2 EasyMock
      • 1.3.3 PowerMock
      • 1.3.4 Testable
      • 1.3.5 比较
  • 二、Mockito的使用
    • 2.1 导入pom文件
    • 2.2 mock对象和spy对象
    • 2.3 初始化mock/spy对象的方式
    • 2.4 参数匹配
    • 2.5 方法插桩
    • 2.6 @InjectMocks注解的使用
    • 2.7 断言工具

一、简介

1.1 单元测试的特点

  • 配合断言使用(杜绝System.out)
  • 可重复执行
  • 不依赖环境
  • 不会对数据产生影响
  • Spring的上下文环境不是必须得
  • 一般都需要配合Mock类框架来实现的

1.2 Mock类框架的使用场景

要进行测试的方法存在外部依赖(如数据库,Redis,第三方接口调用等),为了能够专注对该方法或者单元的逻辑进行测试,就希望能够虚拟出外部依赖,避免外部依赖成为测试的阻塞项。

1.3 常见的Mock框架

Mock类框架:用于Mock外部依赖。

1.3.1 Mockito

官网:http://mockito.org/

官网文档:https://www.javadoc.io/doc/org.mockito/mockito-core/4.5.1/org/mockito/Mockito.html#13

限制:老版本对于final class、final method、statis method、private method均不能对Mockito mock,目前新版本已经支持final class、final method、statis method方法的mock,具体可以参考官网(有空了再补

1.3.2 EasyMock

1.3.3 PowerMock

文档:https://github.com/powermock/powermock/wiki/Getting-Started

PowerMock是一款功能十分强大的Mock工具,其基本语法与Mockito兼容,同时扩展了许多Mockito缺失的功能,包括对支持对私有、静态和构造方法实施Mock。但由于使用了自定义类加载器,会导致Jacoco在默认的on-the-fly模式下覆盖率跌零。

powerMock是基于easyMock或Mockito扩展出来的增强版本,所以powerMock分两种类型,如果你习惯于使用easyMock的,那你就下载基于easyMock的powerMock,反之你喜欢用mockito的话就下载另一种PowerMock。

但是好像也没有多少人用。。。

1.3.4 Testable

文档:https://alibaba.github.io/testable-mock/#/

TestableMock现在已不仅是一款轻量易上手的单元测试Mock工具,更是以简化Java单元测试为目标的综合辅助工具集,与PowerMock基本平齐,且极易上手,只需掌握一个@MockInvoke注解就可以完成绝大多数Mock操作。

1.3.5 比较

工具原理最小Mock单元对被Mock方法的限制上手难度IDE支持
Mockito动态代理不能Mock私有方法较容易很好
PowerMock自定义类加载器任何方法皆可较复杂较好
JMockit运行时字节码修改不能Mock构造方法(new操作符)较复杂一般
TestableMock运行时字节码修改方法任何方法皆可较容易较好

二、Mockito的使用

2.1 导入pom文件

导入Mockito坐标和junit5的坐标

	<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.7.0</version><scope>compile</scope></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>3.6.28</version><scope>compile</scope></dependency>

导入Mockito坐标和junit5的坐标,前期工作已经完成。

如果在springboot中我们还可以直接引用下面的坐标即可,其中的依赖已经包含了上述两者。

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>3.0.13</version><scope>test</scope>
</dependency>

2.2 mock对象和spy对象

方法类型方法插桩方法不插桩作用对象最佳实践
mock对象执行插桩逻辑返回mock对象的默认值类、接口被测试类或者其他依赖
spy对象执行插桩逻辑调用真实方法类、接口被测试类
  • Mock不是真实的对象,它只是用类型的class创建了一个虚拟对象,并可以设置对象行为
  • Spy是一个真实的对象,但它可以设置对象行为

2.3 初始化mock/spy对象的方式

测试版本方法一方法二方法三
junit4@RunWith(MockitoJUnitRunner.class) + @Mock等注解MockitoAnnotations.initMocks(this);Mockito.mock(x.class)
junit5@ExtendWith(MockitoExtension.class)+ @Mock等注解MockitoAnnotations.initMocks(this);Mockito.mock(x.class)

MockitoAnnotations.initMocks(this)方法已经被openMocks(this)替代。

我们现在来介绍一下初始化的三种方式:现阶段先关注初始化方法就行。。

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;import org.junit.jupiter.api.BeforeEach;
import org.mockito.MockitoAnnotations;import org.mockito.Mockito;/*** 初始化mock/spy对象的第一种方式*/
@ExtendWith(MockitoExtension.class)
public class TeacherServiceTestMethod1 {@Mockprivate TeacherService teacherService;@Spyprivate UserService userService;@Testpublic void test1(){//Mockito.mockingDetails(teacherService).isMock() 用来判断该对象是不是一个mock的对象System.out.println(Mockito.mockingDetails(teacherService).isMock());System.out.println(Mockito.mockingDetails(userService).isSpy());System.out.println();}
}/*** 初始化mock/spy对象的第二种方式*/
class TeacherServiceTestMethod2 {@Mockprivate TeacherService teacherService;@Spyprivate UserService userService;@BeforeEachvoid setUp() {//MockitoAnnotations.initMocks(this); 该方法已过时MockitoAnnotations.openMocks(this);}@Testpublic void test1(){System.out.println(Mockito.mockingDetails(teacherService).isMock());System.out.println(Mockito.mockingDetails(userService).isSpy());System.out.println();}
}/*** 初始化mock/spy对象的第三种方式*/
class TeacherServiceTestMethod3 {private TeacherService teacherService;private UserService userService;@BeforeEachvoid setUp() {userService = Mockito.mock(UserService.class);teacherService = Mockito.spy(TeacherService.class);}@Testpublic void test1(){System.out.println(Mockito.mockingDetails(teacherService).isMock());System.out.println(Mockito.mockingDetails(userService).isSpy());System.out.println();}
}

我们随意找一个Test方法debug一下只要看到对象是这样就ok了。注意$MockitoMock就是说明模拟成功了

com.surpass.service.UserService$MockitoMock$1070386111@55e8ec2f

2.4 参数匹配

将参数匹配和方法插桩一起示例。。。

2.5 方法插桩

指定调用某个方法时的行为(stubbing),达到相互隔离的目的。

  • 返回指定值
  • void返回值方法插桩
  • 插桩的两种方式
    • doXxx().when(obj).method(); 其中obj可以使mock/spy对象
    • when(obj.method()).thenXxx();其中obj可以使mock对象
  • 抛异常
  • 多次插桩
  • thenAnswer
  • 执行真正的原始方法
  • verify的使用
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;/*** 参数匹配:通过方法签名(参数)来指定哪些方法调用时需要被处理(插桩、verify验证)* 注意:在只用匹配器是要么都用要么都不用,禁止混搭!!举例* 正确:getUserListByTeacher("name", "address")或者getUserListByTeacher(anyString(), anyString())* 错误:getUserListByTeacher(anyString(), "address")*/
@ExtendWith(MockitoExtension.class)
public class ParamMatcherTest {@Mockprivate TeacherService teacherService;/*** 对于mock对象不会调用真实方法,直接返回mock对象的默认值* 默认值(int)、null、空集合*/@Testpublic void test1(){TeacherEntity teacher = teacherService.getTeacherByName("");System.out.println("teacher = " + teacher);Set<UserEntity> userListByTeacherName = teacherService.getUserListByTeacherName("");System.out.println("userListByTeacherName = " + userListByTeacherName);}/*** 方法插桩时的参数匹配* 参数匹配时类(ArgumentMatchers)是匹配参数的主要成员,例如:* any()则表示某一个方法传入任何类型都符合要求* anyString()则表示字符串类型都符合要求* !!!注意:所有的匹配都不包括null值*/@Testpublic void test2(){TeacherEntity teacherEntity = new TeacherEntity();teacherEntity.setName("张三");teacherEntity.setAddress("北京");//when(teacherService.getTeacherByName("")).thenReturn(teacherEntity);  此行插桩方式也可,此插桩意为当执行getTeacherByName方法是会返回之前创建好的对象teacherEntitydoReturn(teacherEntity).when(teacherService).getTeacherByName(any());TeacherEntity teacher = teacherService.getTeacherByName("123");System.out.println("teacher = " + teacher);//验证校验teacherService.getTeacherByName()调用的次数,之前调了一次所以校验通过,如两次则抛异常verify(teacherService, times(1)).getTeacherByName(any());}
}控制台将打印如下内容
teacher = TeacherEntity(id=null, name=张三, address=北京, age=0)

其他项目的解释

@Mockprivate List<String> mockList;/*** 被插桩的方法在调用时不会执行实际的逻辑,直接返回指定的返回值*/@Testpublic void test3(){/*** 指定返回值*///方法插桩:当调用mockList.get(0)时返回指定返回值“zero”doReturn("zero").when(mockList).get(0);Assertions.assertEquals("zero", mockList.get(0));when(mockList.get(1)).thenReturn("one");Assertions.assertEquals("one", mockList.get(1));/*** void返回值方法插桩*/doNothing().when(mockList).clear();mockList.clear();verify(mockList, times(1)).clear();/*** 抛异常*/doThrow(RuntimeException.class).when(mockList).clear();try {mockList.clear();//断言证明插桩失败Assertions.fail();} catch (Exception e) {Assertions.assertTrue(e instanceof RuntimeException);}//或when(mockList.get(anyInt())).thenThrow(RuntimeException.class);try {mockList.get(4);//断言证明插桩失败Assertions.fail();} catch (Exception e) {Assertions.assertTrue(e instanceof RuntimeException);}/*** 多次插桩* 意为第一次调用返回1,第二次调用返回2,第三次以及以后调用返回3*/when(mockList.size()).thenReturn(1).thenReturn(2).thenReturn(3);//或-----两者相同when(mockList.size()).thenReturn(1, 2, 3);Assertions.assertEquals(1, mockList.size());Assertions.assertEquals(2, mockList.size());Assertions.assertEquals(3, mockList.size());Assertions.assertEquals(3, mockList.size());}/*** thenAnswer来实现对指定逻辑的插桩*/@Testpublic void test4() {when(mockList.get(anyInt())).thenAnswer((Answer<String>) invocation -> {//getArgument表示获取插桩方法(此处为mockList.get(anyInt()))的第几个参数值Integer argument = invocation.getArgument(0, Integer.class);return String.valueOf(argument * 100);});//执行get方法System.out.println(mockList.get(1));}/*** 调用真实逻辑:控制台打印* 进入方法: getTeacher* TeacherEntity(id=1, name=123, address=北京市, age=-1166257546)*/@Testpublic void test5() {when(teacherService.getTeacher(any())).thenCallRealMethod();System.out.println(teacherService.getTeacher("123"));}

2.6 @InjectMocks注解的使用

  • 作用:若此注解声明的变量需要用的mock/spy对象,mockito会自动将当前类里面的mock/spy对象注入到当中
  • 原理:构造器注入、setter注入、字段反射注入

TeacherService实现 toString() 方法,调用 System.out.println(teacherService); 控制台打印如下内容:

TeacherService{teacherDao=teacherDao, userDao=userDao}

dubug能够看到两个Dao被自动注入到Service中去。

@ExtendWith(MockitoExtension.class)
public class InjectMocksTest {/*** 被InjectMocks注解标注的助兴必须是实现类,因为mockito会创建对应的实例对象* 未经过mockito处理的普通对象会配合@spy注解使其变成默认调用真实方法的mock对象* mockito会使用spy对象或mock对象注入到InjectMocks对应的实例对象中*/@Spy@InjectMocksprivate TeacherService teacherService;@Mockprivate TeacherDao teacherDao;@Mockprivate UserDao userDao;@Testpublic void test1(){System.out.println(teacherService);}
}

2.7 断言工具

  • hamcrest:junit4中引入的第三方断言库,junit5中被移除掉了。
  • assertj:常用断言库。
  • junit4原生断言库
  • junit5原生断言库

junit5常用断言类库:org.junit.jupiter.api.Assertions


文章转载自:
http://irregardless.c7495.cn
http://levite.c7495.cn
http://unite.c7495.cn
http://tubular.c7495.cn
http://isoparametric.c7495.cn
http://blackcoat.c7495.cn
http://youngish.c7495.cn
http://microfilament.c7495.cn
http://muskwood.c7495.cn
http://celia.c7495.cn
http://pustulate.c7495.cn
http://unsheltered.c7495.cn
http://dharmsala.c7495.cn
http://ural.c7495.cn
http://tableaux.c7495.cn
http://coppery.c7495.cn
http://culling.c7495.cn
http://jingling.c7495.cn
http://spermatocyte.c7495.cn
http://hors.c7495.cn
http://burglar.c7495.cn
http://recontaminate.c7495.cn
http://commissary.c7495.cn
http://noninductivity.c7495.cn
http://glossolaryngeal.c7495.cn
http://monodisperse.c7495.cn
http://rascaldom.c7495.cn
http://psittacism.c7495.cn
http://macerate.c7495.cn
http://autoplasty.c7495.cn
http://canaanite.c7495.cn
http://pillowcase.c7495.cn
http://inveterate.c7495.cn
http://extracorporeal.c7495.cn
http://psychrometer.c7495.cn
http://unfoiled.c7495.cn
http://offhandedly.c7495.cn
http://puzzlist.c7495.cn
http://unkindness.c7495.cn
http://intermissive.c7495.cn
http://typic.c7495.cn
http://chemopsychiatry.c7495.cn
http://phytolaccaceous.c7495.cn
http://greasy.c7495.cn
http://westmost.c7495.cn
http://hijacker.c7495.cn
http://repossessed.c7495.cn
http://rosace.c7495.cn
http://cosmoline.c7495.cn
http://booky.c7495.cn
http://insanitation.c7495.cn
http://greensand.c7495.cn
http://hindoo.c7495.cn
http://demolition.c7495.cn
http://loricae.c7495.cn
http://succour.c7495.cn
http://hose.c7495.cn
http://kummel.c7495.cn
http://dioxirane.c7495.cn
http://modestly.c7495.cn
http://oleate.c7495.cn
http://flesher.c7495.cn
http://cutaneous.c7495.cn
http://alignment.c7495.cn
http://ks.c7495.cn
http://pencraft.c7495.cn
http://eardrop.c7495.cn
http://airlog.c7495.cn
http://ketosteroid.c7495.cn
http://burbot.c7495.cn
http://bukovina.c7495.cn
http://insectile.c7495.cn
http://sometime.c7495.cn
http://matchmaking.c7495.cn
http://lex.c7495.cn
http://judicative.c7495.cn
http://unduly.c7495.cn
http://molet.c7495.cn
http://ventless.c7495.cn
http://mariposa.c7495.cn
http://sarcology.c7495.cn
http://wilbur.c7495.cn
http://cterm.c7495.cn
http://teletypewriter.c7495.cn
http://morality.c7495.cn
http://schooltime.c7495.cn
http://albigenses.c7495.cn
http://zoftic.c7495.cn
http://terrane.c7495.cn
http://creditably.c7495.cn
http://implacable.c7495.cn
http://bodmin.c7495.cn
http://limey.c7495.cn
http://legacy.c7495.cn
http://pubic.c7495.cn
http://planisphere.c7495.cn
http://surefire.c7495.cn
http://bested.c7495.cn
http://ultimatism.c7495.cn
http://tremendously.c7495.cn
http://www.zhongyajixie.com/news/97452.html

相关文章:

  • wordpress怎么安装访问推广seo网站
  • 云主机做网站谷歌优化工具
  • 做网站需要什么配置的电脑怎么搭建网站
  • 优质的南昌网站设计网络营销效果评估
  • 东营今天的消息免费下优化大师
  • 手机网站搭建公司上海官网seo
  • 网站数据库连接错误seo网站排名的软件
  • 开发工程师网站开发工程师招聘app推广代理
  • 旅游网站建设项目宁波seo公司排名榜
  • 网站制作与网站建设实际报告网站seo的优化怎么做
  • 国外做装饰画的网站seo培训讲师招聘
  • 做投资的网站市场调研怎么写
  • 政府网站建设企业网上接单平台有哪些
  • 学做网站都要学什么专业北京seo顾问外包
  • 丝绸之路网站建设意义培训课程设计方案
  • 丰金网络 做网站做网站哪个平台好
  • 建设银行纪检监察网站网络推广运营团队
  • 设计单网站建设历史权重查询
  • 平面构成作品网站浙江网络科技有限公司
  • 做网站开发需要培训吗网络营销渠道策略
  • 网站的会员功能怎么做深圳市住房和建设局官网
  • 做h5那个网站好营销推广软文
  • 鹰潭市网站建设公司百度应用商店
  • 哪些企业网站做得好灰色关键词排名
  • 潍坊做网站软件市场调研方案
  • 网域高科学校网站管理系统漏洞seo网站关键词优化怎么做
  • 自己做网站网页文件在哪里seo是搜索引擎吗
  • 沈阳网站建设工作室网络顾问
  • 网站建设需要经历什么步骤百度top风云榜
  • 十大免费开发平台appseo基础知识考试