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

网站首页快照不更新做直销去哪里找客户

网站首页快照不更新,做直销去哪里找客户,开发一个简单的系统,网站标题优化怎么做介绍 Mockito 是一个广泛使用的 Java 测试框架,它提供了简洁而强大的功能,用于模拟(mock)和验证对象的行为,尤其是在单元测试中。 当我们需要测试某个类的功能时,但又不希望依赖其外部组件或复杂的对象时…

介绍

Mockito 是一个广泛使用的 Java 测试框架,它提供了简洁而强大的功能,用于模拟(mock)和验证对象的行为,尤其是在单元测试中。

当我们需要测试某个类的功能时,但又不希望依赖其外部组件或复杂的对象时,可以使用 Mockito 来创建模拟对象,这些模拟对象可以控制方法返回值、抛出异常或执行特定的逻辑。Mockito 使得测试变得更加独立、可靠和可维护,特别是在测试依赖较多或外部系统交互的代码时。


从一个例子开始

以下示例模拟了 List,因为大多数人都熟悉 List 的使用方法,例如 add、get、clear 方法。

import static org.mockito.Mockito.*;// 开始 mock List对象
List mockedList = mock(List.class);// 使用 mock 对象
mockedList.add("one");
mockedList.clear();// 验证
verify(mockedList).add("one");
verify(mockedList).clear();

创建模拟对象后,mock 将记住所有交互(交互一般是函数调用)。然后,你可以有选择地验证感兴趣的任何交互。


添加存根 stubbing

存根是 stubbing 的中文翻译,由于存根一词并不利于理解,因此下文索性统一使用 stubbing

stubbing 是模拟(mock)对象行为的过程,指的是为模拟对象的方法调用提供预定义的返回值或行为。简单来说,stubbing 就是告诉 Mockito,当模拟对象的方法被调用时,应该返回什么结果或者执行什么操作。

LinkedList mockedList = mock(LinkedList.class);// stubbing
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());// 打印 first
System.out.println(mockedList.get(0));// 抛出 RuntimeException
System.out.println(mockedList.get(1));// 打印 null
System.out.println(mockedList.get(999));// verify stubbing 一般是多余的,这里为了演示
verify(mockedList).get(0);

默认情况下,Mockito 会为所有方法的返回值提供自动模拟。例如,返回 null、原始值(如 0 表示 int 或 Integer,false 表示 boolean 或 Boolean)或空集合(如空 List、空 Map 等)。这种默认行为使得即使没有明确进行 Stubbing,模拟对象仍然能安全地返回合理的默认值。

Stubbing 是指通过明确的指令为模拟对象的方法调用提供预定义的返回值或行为。一旦对某个方法进行了 Stubbing,不管该方法被调用多少次,都会返回 stubbing 值。 

在多次对同一个方法进行 Stubbing 后,最后一次设置的 Stubbing 会覆盖之前的所有设置


参数匹配器 anyXXX()

any() 系列:匹配任意值(包括null),比如:

  • anyString()
  • anyInt()
  • anyList()
  • any(Class<T>)

eq():匹配特定值(需精确相等)。

// 对于 anyInt() 都将返回 element
when(mockedList.get(anyInt())).thenReturn("element");// 打印 element
System.out.println(mockedList.get(999));// 可以用 anyInt() 做验证
verify(mockedList).get(anyInt());

如果使用参数匹配器,则所有参数必须由参数匹配器提供。

// 验证调用了此方法,并且第三个参数为 third argument
verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));// 抛异常,因为第三个参数是具体值
verify(mock).someMethod(anyInt(), anyString(), "third argument");

不能在 verify 或 stubbing 方法之外使用 anyXXX(), eq() 等方法。


验证调用次数 verify

// 开始 mock
mockedList.add("once");mockedList.add("twice");
mockedList.add("twice");mockedList.add("three times");
mockedList.add("three times");
mockedList.add("three times");// 以下两种方式完全等价,验证只调用过一次
// 强调一下,第一种方式仅代表调用过一次,不是至少一次
verify(mockedList).add("once");
verify(mockedList, times(1)).add("once");// 校验调用的确切次数
verify(mockedList, times(2)).add("twice");
verify(mockedList, times(3)).add("three times");// 校验没有调用过
verify(mockedList, never()).add("never happened");
verify(mockedList, times(0)).add("never happened");// 校验至少、至多调用次数
verify(mockedList, atMostOnce()).add("once");
verify(mockedList, atLeastOnce()).add("three times");
verify(mockedList, atLeast(2)).add("three times");
verify(mockedList, atMost(5)).add("three times");

注意:times(1) 是默认值。 因此,显式使用 times(1) 可以是省略


排除冗余调用 verifyNoMoreInteractions

verifyNoMoreInteractions 用于验证模拟对象上是否没有多余的交互发生。

该方法通常在测试的最后阶段使用,确保模拟对象的行为完全符合预期。例如,在一个测试中,可能先调用某些方法并验证这些调用,之后使用 verifyNoMoreInteractions 确保没有其他未预料到的调用发生。

// 开始 mock
mockedList.add("one");
mockedList.add("two");// 调用过 add("one")
verify(mockedList).add("one");// 失败:因为还调用过 add("two")
verifyNoMoreInteractions(mockedList);


对连续调用进行 stubbing

有时我们需要为相同的 stubbing 使用不同的 返回值/异常,典型的用例可能是模拟迭代器。

when(mock.someMethod("some arg"))
.thenThrow(new RuntimeException())
.thenReturn("foo");// 第一次调用 throws runtime exception
mock.someMethod("some arg");// 第二次调用 打印foo
System.out.println(mock.someMethod("some arg"));// 之后的调用都将打印foo,因为以最后一次为准
System.out.println(mock.someMethod("some arg"));

连续 stubbing 的可以简化代码为:

// 直接模拟调用一次、两次、三次的返回结果
when(mock.someMethod("some arg")).thenReturn("one", "two", "three");

警告:如果不是流式调用,而是使用相同的匹配器或参数进行多个 stubbing ,则会以最后一个 stubbing 为准(即覆盖前面所有的 stubbing)

when(mock.someMethod("some arg")).thenReturn("one");
when(mock.someMethod("some arg")).thenReturn("two");// 接下来,所有的 mock.someMethod("some arg") 都将返回 two


模拟回调 Answer

这是另一个有争议的功能,最初并未包含在 Mockito 中。因为使用 thenReturn() 或 thenThrow()  函数应该足以进行测试任何干净简单的代码。但是,如果确实需要使用通用 Answer 接口进行 stubbing,下面是一个示例:

when(mock.someMethod(anyString())).thenAnswer(new Answer() {public Object answer(InvocationOnMock invocation) {Object[] args = invocation.getArguments();Object mock = invocation.getMock();return "called with arguments: " + Arrays.toString(args);}
});// 下面将打印 called with arguments: [foo]
System.out.println(mock.someMethod("foo"));


doXXX() 系列方法

方法作用使用场景示例
doReturn()指定方法返回值用于无法在 when() 中调用的方法(如 finalprivatedoReturn("value").when(mock).method()
doThrow()模拟抛出异常用于模拟抛出异常的场景,常见于 void 方法或带异常的调用doThrow(new Exception()).when(mock).method()
doAnswer()自定义行为用于根据输入自定义方法的返回值或行为doAnswer(invocation -> {}).when(mock).method()
doNothing()模拟不做任何事情用于 void 方法,确保它被调用但不执行实际逻辑doNothing().when(mock).method()
doCallRealMethod()调用真实方法用于测试中需要部分调用真实方法的场景

doCallRealMethod().when(mock).method()


监视真实物体 spy

使用 spy 时,调用的是实际方法,所以需要小心。Spy 适用于遗留代码或特殊场景,但不应过度使用。Mockito 1.8 之前,spy 并不支持真正的部分模拟,认为部分模拟是一个不好的做法。但后来发现,在某些情况下(比如与第三方接口交互或临时重构遗留代码),部分模拟是有用的。

List list = new LinkedList();
List spy = spy(list);// stubbing size方法
when(spy.size()).thenReturn(100);// 调用真实方法,添加两个元素
spy.add("one");
spy.add("two");// 调用真实方法,打印one
System.out.println(spy.get(0));// 调用 stubbing 方法吗打印 100
System.out.println(spy.size());


重置模拟对象 reset

List mock = mock(List.class);
when(mock.size()).thenReturn(10);
mock.add(1);// reset 之后以上的所有 stubbing 将会失效
reset(mock);


严格 Stubbing

@Test
public void givenUnusedStub() {// 假设这个 stubbing 没有使用when(mockList.add("one")).thenReturn(true);// 这个使用了when(mockList.get(anyInt())).thenReturn("hello");assertEquals("List should contain hello", "hello", mockList.get(1));
}

当我们运行这个单元测试时,Mockito 将检测未使用的 stubbing 并抛出 UnnecessaryStubbingException:表明第一个 when 是多余的,因为没有在单元测试中调用此方法

Mockito 也提供了一些方法绕过严格 stubbing 的检查:

  • Mockito.lenient()
  • @MockitoSettings(strictness = Strictness.LENIENT)


模拟静态方法 mockStatic

 为了确保静态模拟保持临时状态,建议在 try-with-resources 构造中定义范围。 在下面的示例中,除非被模拟,否则 Foo 类型的 static 方法将返回 foo:

assertEquals("foo", Foo.method());try (MockedStatic mocked = mockStatic(Foo.class)) {mocked.when(Foo::method).thenReturn("bar");assertEquals("bar", Foo.method());mocked.verify(Foo::method);
}
// 还是成功,不会被 try 的内部影响
assertEquals("foo", Foo.method());


模拟对象构造 mockConstruction

为了确保构造函数 mock 保持临时状态,建议在 try-with-resources 构造中定义范围。 在下面的示例中,Foo 类型的构造将生成一个 mock:

assertEquals("foo", new Foo().method());try (MockedConstruction mocked = mockConstruction(Foo.class)) {Foo foo = new Foo();when(foo.method()).thenReturn("bar");assertEquals("bar", foo.method());verify(foo).method();
}assertEquals("foo", new Foo().method());


捕获参数 ArgumentCaptor

ArgumentCaptor 用于捕获方法调用时传递的参数,以便后续进行验证或断言。

ArgumentCaptor 必须与 verify 一起使用,单独使用 captor.capture() 不会产生任何效果。捕获的参数类型必须与实际的参数类型匹配,否则会抛出异常。

List mockList = Mockito.mock(List.class);
ArgumentCaptor<String> arg = ArgumentCaptor.forClass(String.class); mockList.add("one");
Mockito.verify(mockList).add(arg.capture());ssertEquals("one", arg.getValue());


参考

Mockito - mockito-core 5.18.0 javadoc

https://www.baeldung.com/mockito-series

http://www.dtcms.com/wzjs/425952.html

相关文章:

  • 东海县建网站品牌策划案
  • 做自媒体的有哪些素材网站免费做做网站
  • 做百度手机网站点击厦门seo外包
  • 丹江口做网站宣传推广方式有哪些
  • 班级网站建设模板下载搜索引擎排名2020
  • 网站布局的好坏的几个要素英文外链seo兼职在哪里找
  • 茂名建站模板搭建福建seo搜索引擎优化
  • 软件开发专业课程有哪些百度seo关键词排名优化软件
  • 织梦网站根目录标签网络营销工作内容
  • 酒店 深圳 网站建设打开网址跳转到国外网站
  • 网站cnameseo是什么姓氏
  • 网站跨平台html网页制作网站
  • wordpress标签样式表seo是指什么意思
  • 房屋建筑设计网站黄页引流推广网站入口
  • 保定 网站建设深圳关键词推广整站优化
  • 医院网站 功能今日头条最新消息
  • 网络服务器有哪些长春网站快速优化排名
  • 双流规划建设管理局网站企业在线培训系统
  • 网站做的好的公司免费企业网站建设流程
  • 织梦网站导航固定明星百度指数在线查询
  • 东莞高埗做网站哪个公司好中国国家培训网是真的吗
  • 网站如何做se完整的社群营销方案
  • 网站建设创业计划书模板范文百度推广手机版
  • html模板 网站泰州seo
  • 美术馆网站建设方案宁波做网站的公司
  • 建站公司前途百度app下载官方免费下载最新版
  • 网站登录界面html怎样进行seo推广
  • 建湖做网站找哪家好外贸seo软件
  • 政府网站建设指导河南百度推广电话
  • dz论坛网站建设seo+网站排名