Mockito教程(单测mock)

1 Mockito 介绍 [3]

1.1 Mockito是什么?

Mockito是mocking框架,它让你用简洁的API做测试。而且Mockito简单易学,它可读性强和验证语法简洁。

1.2 为什么需要Mock

测试驱动的开发( TDD)要求我们先写单元测试,再写实现代码。在写单元测试的过程中,我们往往会遇到要测试的类有很多依赖,这些依赖的类/对象/资源又有别的依赖,从而形成一个大的依赖树,要在单元测试的环境中完整地构建这样的依赖,是一件很困难的事情。如下图所示:

 

为了测试类A,我们需要Mock B类和C类(用虚拟对象来代替)如下图所示:

 

1.3 Stub和Mock异同[1]

  • 相同:Stub和Mock都是模拟外部依赖
  • 不同:Stub是完全模拟一个外部依赖, 而Mock还可以用来判断测试通过还是失败

在软件测试中,"Stub"(桩)和"Mock"(模拟)都是用来替代或模仿实际组件的测试工具,用于隔离被测系统的一部分,从而可以专注于测试某一个具体的模块。尽管它们有相似的目的,但在使用方式和功能上有一些关键区别:

1. **Stub(桩)**:
- Stub是一种简单的替代对象,通常用于模拟复杂的系统或外部服务。它提供固定的响应或行为,这些响应或行为是预先定义好的,不需要根据输入动态变化。
- Stub主要用于控制测试环境,在测试过程中提供一致性和可预测性。
- 它们通常比较简单,可能只是简单地返回一个预设的数据集或者执行一个预定义的操作
- Stub常用于当一个组件需要与数据库或其他外部系统交互时,但测试时并不关心这些系统的具体实现细节。

2. **Mock(模拟)**:
- Mock对象比Stub更复杂,它不仅可以模拟对象的行为还可以记录和验证方法调用的次数以及顺序
- Mock允许你在测试时指定期望的方法调用,并检查这些调用是否按预期发生。如果方法没有按照预期的方式被调用,Mock可能会抛出异常或失败。
- Mock也可以设置预期的返回值,甚至可以根据传入的不同参数返回不同的结果。
- 使用Mock时,你可以更精细地控制测试条件,并且能够验证代码中的逻辑是否正确地处理了各种情况。

总结来说,Stub主要用于提供静态的或固定的行为,而Mock则更多地用于验证对象之间的交互是否符合预期。在实际开发中,根据测试的具体需求选择合适的工具是非常重要的。

2 使用Mockito [2][4]

2.1 验证行为

 1 @Test
 2     public void verify_behaviour(){
 3         //模拟创建一个List对象
 4         List mock = mock(List.class);
 5         //使用mock的对象
 6         mock.add(1);
 7         mock.clear();
 8         //验证add(1)和clear()行为是否发生
 9         verify(mock).add(1);
10         verify(mock).clear();
11     }

2.2 模拟我们所期望的结果

@Test
    public void when_thenReturn(){
        //mock一个Iterator类
        Iterator iterator = mock(Iterator.class);
        //预设当iterator调用next()时第一次返回hello,第n次都返回world
        when(iterator.next()).thenReturn("hello").thenReturn("world");
        //使用mock的对象
        String result = iterator.next() + " " + iterator.next() + " " + iterator.next();
        //验证结果
        assertEquals("hello world world",result);
    }

1 @Test(expected = IOException.class)
2     public void when_thenThrow() throws IOException {
3         OutputStream outputStream = mock(OutputStream.class);
4         OutputStreamWriter writer = new OutputStreamWriter(outputStream);
5         //预设当流关闭时抛出异常
6         doThrow(new IOException()).when(outputStream).close();
7         outputStream.close();
8     }

 

posted on 2024-08-27 14:36  gogoy  阅读(98)  评论(0编辑  收藏  举报

导航