欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

编写 Java 单元测试:使用 JUnit 框架和 Mockito 框架快速入门》,请阅读!!!!!

最编程 2024-10-14 06:58:08
...

目录

  • 1.相关框架简介
    • 1.Mockito框架介绍
    • 2.JUnit框架介绍
  • 2.Mockito框架中相关注解的用法
  • 3.JUnit框架中相关注解的用法
  • 4.创建Mock对象的方式
  • 5.打桩:Mockito框架中模拟对象的行为
  • 6.验证:Mockito框架中的verify方法
  • 7.断言:使用Assertions类中的方法来进行断言验证

1.相关框架简介

1.Mockito框架介绍

Mockito框架是一个用于Java的开源框架,用于进行单元测试时的模拟对象创建和行为验证。Mockito框架可以帮助开发人员创建测试时需要的模拟对象,以便在测试过程中模拟或替代真实对象的行为

2.JUnit框架介绍

JUnit是一个Java编程语言的单元测试框架。
它提供了编写和运行单元测试的工具和框架。
JUnit的设计目标是简单易用,以支持测试驱动开发(TDD)的开发过程。
JUnit提供了一组注解和断言方法,用于编写测试用例和验证预期结果。
它也提供了测试运行器(TestRunner)来执行测试,并生成测试报告。
JUnit可以与其他开发工具和构建工具(如Maven和Gradle)集成,以便更方便地执行和管理单元测试。

2.Mockito框架中相关注解的用法

在Mockito框架中,有几个常用的注解用于定义和管理测试中的模拟对象和行为。这些注解包括:

  1. @Mock:用于创建一个模拟对象。当使用该注解标注一个字段时,Mockito会自动创建一个模拟对象并将其注入到测试类中。
@Mock
private SomeClass someMock;
  1. @Spy:与@Mock类似,用于创建一个模拟对象。不同之处在于,@Spy会将真实对象的部分行为保留下来,并允许对其进行部分模拟。
@Spy
private SomeClass someSpy;
  1. @InjectMocks:用于注入模拟对象到被测试类中的字段或构造函数参数中。当使用该注解标注一个类时,Mockito会尝试自动将模拟对象注入到该类中。
@InjectMocks
private SomeService someService;
  1. @Captor:用于捕获方法参数的值,以便用于后续的断言或验证。
@Captor
private ArgumentCaptor<String> captor;
  1. @RunWith(MockitoJUnitRunner.class):用于指定运行测试时使用的Runner,通过指定MockitoJUnitRunner.class,可以自动初始化模拟对象的注解。
@RunWith(MockitoJUnitRunner.class)
public class SomeTest {
    // Test methods
}

除了上述注解外,Mockito还提供了一些其他的注解,如@MockBean、@MockStatic等,可以根据具体的测试需求选择合适的注解进行使用。

3.JUnit框架中相关注解的用法

在JUnit中,有几个常用的注解可以用来标记测试方法和测试类的行为和特性。以下是JUnit中一些常见的注解及其用法:

  1. @Test:用于标记测试方法。被注解的方法将被JUnit框架执行为测试方法。测试方法应该返回void类型,并且没有参数。
@Test
public void testMethod() {
    // 测试逻辑
}
  1. @Before:用于标记在每个测试方法之前需要执行的代码。被注解的方法将在每个测试方法执行前被调用。
@Before
public void setUp() {
    // 初始化操作
}
  1. @After:用于标记在每个测试方法之后需要执行的代码。被注解的方法将在每个测试方法执行后被调用。
@After
public void tearDown() {
    // 清理操作
}
  1. @BeforeClass:用于标记在整个测试类中只需要执行一次的代码。被注解的方法将在所有测试方法之前被调用。
@BeforeClass
public static void setUpClass() {
    // 静态初始化操作
}
  1. @AfterClass:用于标记在整个测试类中只需要执行一次的代码。被注解的方法将在所有测试方法之后被调用。
@AfterClass
public static void tearDownClass() {
    // 静态清理操作
}
  1. @Ignore:用于标记一个测试方法或测试类,表示该测试方法或测试类被忽略,不会被执行。
@Ignore
public void ignoredTest() {
    // 被忽略的测试方法
}

以上是JUnit中一些常见的注解及其用法。使用这些注解可以更方便地编写和管理测试代码。

4.创建Mock对象的方式

在Mockito框架中,可以使用以下几种方式来创建mock对象:

  1. 使用静态方法mock()创建mock对象:

    List<String> mockedList = Mockito.mock(List.class);
    
  2. 使用注解@Mock创建mock对象:

    @Mock
    List<String> mockedList;
    
  3. 使用注解@InjectMocks创建被注入mock对象:

    @InjectMocks
    private Service service;
    
    @Mock
    private Dao dao;
    
  4. 使用mockitoAnnotations.initMocks()初始化注解创建的mock对象:

    public class MyTest {
        @Mock
        private List<String> mockedList;
        
        @Before
        public void setup() {
            MockitoAnnotations.initMocks(this);
        }
        
        // 测试代码
    }
    

5.打桩:Mockito框架中模拟对象的行为

在Mockito框架中,可以使用打桩(stub)的方式来定义模拟对象的行为
打桩是指当某个特定的方法被调用时,模拟对象应该返回什么值或者执行什么操作。

以下是打桩的一些常见用法:

  1. 指定方法调用的返回值:
when(mockObject.someMethod()).thenReturn(someValue);

当模拟对象的someMethod()方法被调用时,返回someValue

  1. 当方法被调用时抛出异常:
when(mockObject.someMethod()).thenThrow(SomeException.class);

当模拟对象的someMethod()方法被调用时,抛出SomeException异常。

  1. 配置连续的返回值:
when(mockObject.someMethod())
    .thenReturn(value1)
    .thenReturn(value2)
    .thenReturn(value3);

当模拟对象的someMethod()方法第一次被调用时,返回value1,第二次调用返回value2,第三次调用返回value3

  1. 配置方法的返回值通过参数动态计算:
when(mockObject.someMethod(anyInt()))
    .thenAnswer(invocation -> {
        int arg = invocation.getArgument(0);
        return arg * 2;
    });

当模拟对象的someMethod()方法被调用时,根据传入的参数动态计算返回值。

  1. 配置使方法真实地执行:
when(mockObject.someMethod()).thenCallRealMethod();

当模拟对象的someMethod()方法被调用时,实际执行真正的方法逻辑。

这些只是打桩的一些常见用法,Mockito提供了更多的功能来灵活地配置模拟对象的行为。在使用时,根据具体的需求选择适合的打桩方式。

6.验证:Mockito框架中的verify方法

Mockito框架中的verify方法用于验证某个方法是否被调用,并可以进一步验证调用的次数、参数等。

基本用法:

// 创建一个mock对象
SomeClass someObject = Mockito.mock(SomeClass.class);

// 调用被测试的方法
someObject.someMethod();

// 验证方法是否被调用
Mockito.verify(someObject).someMethod();

上述代码中,verify方法用于验证someMethod方法是否被调用。

常用的验证方法:

  • verify(mock).method():验证某个方法是否被调用过。
  • verify(mock, times(n)).method():验证某个方法被调用了n次。
  • verify(mock, atLeast(n)).method():验证某个方法被调用至少n次。
  • verify(mock, atMost(n)).method():验证某个方法最多被调用n次。
  • verify(mock, never()).method():验证某个方法从未被调用过。
  • verify(mock, timeout(millis)).method():验证某个方法在规定的时间内被调用。

参数匹配:

// 参数匹配
Mockito.verify(someObject).someMethod(Mockito.anyInt());

上述代码中,anyInt()方法用于匹配方法的参数。

  1. 使用verify()方法来验证方法是否被调用:
// 创建mock对象
List<String> mockList = Mockito.mock(List.class);

// 调用mock对象的方法
mockList.add("hello");

// 验证方法是否被调用
Mockito.verify(mockList).add("hello");
  1. 使用times()方法指定方法被调用的次数:
// 验证方法被调用1次
Mockito.verify(mockList, Mockito.times(1)).add("hello");

// 验证方法被调用2次
Mockito.verify(mockList, Mockito.times(2)).add("hello");
  1. 使用never()方法验证方法是否没有被调用:
// 验证方法没有被调用
Mockito.verify(mockList, Mockito.never()).add("hello");
  1. 使用any()方法来匹配方法参数的任意值:
// 验证方法被调用,且参数为任意值
Mockito.verify(mockList).add(Mockito.anyString());
  1. 使用eq()方法来匹配特定的参数:
// 验证方法被调用,且参数为"hello"
Mockito.verify(mockList).add(Mockito.eq("hello"));
  1. 使用argumentCaptor()方法来捕获方法的参数并进行断言:
// 创建ArgumentCaptor对象
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);

// 调用mock对象的方法
mockList.add("hello");

// 使用ArgumentCaptor捕获参数
Mockito.verify(mockList).add(captor.capture());

// 断言捕获的参数值
assertEquals("hello", captor.getValue());

7.断言:使用Assertions类中的方法来进行断言验证

在Mockito框架中,可以使用Assertions类中的方法来进行断言验证。以下是一些常用的Assertions方法:

  1. assertEquals(expected, actual):验证两个对象是否相等。
String expected = "Hello";
String actual = "Hello";
Assertions.assertEquals(expected, actual);
  1. assertNotEquals(unexpected, actual):验证两个对象是否不相等。
String unexpected = "Hello";
String actual = "World";
Assertions.assertNotEquals(unexpected, actual);
  1. assertNull(actual):验证对象是否为null。
String actual = null;
Assertions.assertNull(actual);
  1. assertNotNull(actual):验证对象是否不为null。
String actual = "Hello";
Assertions.assertNotNull(actual);
  1. assertTrue(condition):验证条件是否为真。
boolean condition = true;
Assertions.assertTrue(condition);
  1. assertFalse(condition):验证条件是否为假。
boolean condition = false;
Assertions.assertFalse(condition);
  1. assertSame(expected, actual):验证两个对象是否是同一个对象。
String expected = "Hello";
String actual = "Hello";
Assertions.assertSame(expected, actual);
  1. assertNotSame(unexpected, actual):验证两个对象是否不是同一个对象。
String unexpected = "Hello";
String actual = "World";
Assertions.assertNotSame(unexpected, actual);
  1. assertThrows(expectedException, executable):验证方法是否抛出了指定的异常。
Assertions.assertThrows(NullPointerException.class, () -> {
  String s = null;
  s.length();
});

以上是Assertions类中的一些常用方法,可以根据需要选择合适的方法来进行断言验证。

推荐阅读