-
单元测试:单元测试旨在对一小块代码进行测
-
JUnit
-
JUnit是一个用于编写和运行测试的框架,每个测试都是一个方法,包含特定场景下将执行的部分代码,比较预期输出和实际输出,以实现代码验证
-
测试类通常包含三个阶段:准备,测试和清理
-
@SpringBootTest class UnitTestApplicationTests { Friendships friendships; @BeforeAll public static void beforeClass() { // 这个方法仅在初始化阶段执行一次 System.out.println("这个方法仅在初始化阶段执行一次"); } @BeforeEach public void before() { friendships = new Friendships(); friendships.makeFriends("Joe", "Audrey"); friendships.makeFriends("Joe", "Peter"); friendships.makeFriends("Joe", "Michael"); friendships.makeFriends("Joe", "Britney"); friendships.makeFriends("Joe", "Paul"); } @Test public void alexDoesNotHaveFriends() { Assertions.assertTrue(friendships.getFriendsList("Alex").isEmpty(),"Alex does not have friends"); } @Test public void joeHas5Friends() { Assertions.assertEquals( 5,friendships.getFriendsList("Joe").size(),"Joe has 5 friends"); } @Test public void joeIsFriendWithEveryone() { List<String> friendsOfJoe = Arrays.asList("Audrey", "Peter", "Michael", "Britney", "Paul"); Assertions.assertTrue(friendships.getFriendsList("Joe") .containsAll(friendsOfJoe)); } @AfterAll public static void afterClass() { // 这个方法仅在所有测试都执行完毕后执行一次 System.out.println("这个方法仅在所有测试都执行完毕后执行一次"); } @AfterEach public void after() { // 这个方法在每个测试执行完毕后都执行 System.out.println("这个方法在每个测试执行完毕后都执行"); } }
-
@BeforeAll指定,方法只在执行类中的测试方法前执行一次,非常适合用于执行大部分乃至全部测试都要求的一般性准备工作
-
@BeforeEach指定,方法将在每个测试方法前运行,可使用他准备测试数据,这样就不用担心后面运行的测试修改数据状态,
-
这两种注解常用于准备数据库数据,创建测试所需的文件等
-
@AfterAll指定的方法在所有测试都结束后运行一次
-
@AfterEach指定的方法在每个测试结束后都执行
-
-
Mockito
-
package com.lpy.unittest; import com.lpy.unittest.entity.FriendsCollection; import com.lpy.unittest.entity.Friendships; import com.lpy.unittest.entity.Person; import org.junit.jupiter.api.*; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import org.springframework.boot.test.context.SpringBootTest; import java.util.Arrays; import java.util.List; import java.util.Objects; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @SpringBootTest @RunWith(MockitoJUnitRunner.class) class MockitoTestApplicationTests { @InjectMocks Friendships friendships; @Mock FriendsCollection friends; @Test public void test(){ Person joe = new Person("Joe"); doReturn(joe).when(friends).findByName("Joe"); assertThat("对象不等", Objects.equals(friends.findByName("Joe"),joe)); System.out.println("---方法结束"); } @Test public void joeHas5Friends() { List<String> expected = Arrays.asList("Audrey", "Peter", "Michael", "Britney", "Paul"); Person joe = spy(new Person("Joe")); doReturn(joe).when(friends).findByName("Joe"); doReturn(expected).when(joe).getFriends(); List<String> joe1 = friendships.getFriendsList("Joe"); assertThat("----",friendships.getFriendsList("Joe").contains("Audrey")); } }
-
Mockito是通过JUnit运行器运行的,他替我们创建所有必须的模拟对象,并将其注入包含测试的类,
-
要让一个类能够使用Mockito注解,必须使用MockitoJUnitRunner运行,@RunWith(MockitoJUnitRunner.class)
-
测试类中使用@InjectMocks标注受测类,以告诉Mockito应将模拟对象注入哪个类
-
@Mock需要指定将Friendships中哪些方法或对象替换为模拟对象,将模拟Friendships这个类中的FriendsCollection对象
-
Mockito Spy的主要特点包括:
- 部分模拟:Spy对象可以在真实对象的基础上进行部分模拟,只模拟我们感兴趣的方法,而其他方法将保持原样。
- 保留真实行为:Spy对象会保留真实对象的行为,除非我们显式地指定了模拟行为。这使得我们可以在需要时调用真实对象的方法。
- 验证方法调用:与其他Mockito功能一样,我们可以使用Spy对象来验证方法的调用次数、参数等。
-
Mockito Spy的应用场景包括:
- 测试私有方法:Spy对象可以用于测试私有方法,通过部分模拟真实对象,我们可以调用私有方法并验证其行为。
- 测试依赖关系:当我们需要测试一个对象,但它依赖于其他对象时,我们可以使用Spy对象来模拟这些依赖关系的行为。
- 测试异常情况:通过Spy对象,我们可以模拟真实对象的异常情况,以测试代码在异常情况下的行为。
-
-
EasyMock
-
package com.lpy.unittest; import com.lpy.unittest.entity.FriendsCollection; import com.lpy.unittest.entity.Friendships; import com.lpy.unittest.entity.Person; import org.easymock.EasyMockRunner; import org.easymock.Mock; import org.easymock.MockType; import org.easymock.TestSubject; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import java.util.Arrays; import java.util.List; import java.util.Objects; import static org.easymock.EasyMock.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @SpringBootTest @RunWith(EasyMockRunner.class) class EasyMockTestApplicationTests { @TestSubject Friendships friendships = new Friendships(); @Mock(type = MockType.NICE) FriendsCollection friends; @Test public void test(){ Person joe = new Person("Joe"); expect(friends.findByName("Joe")).andReturn(joe); replay(friends); assertThat("对象不等", Objects.equals(friends.findByName("Joe"),joe)); System.out.println("---方法结束"); } @Test public void joeHas5Friends() { List<String> expected = Arrays.asList("Audrey", "Peter", "Michael", "Britney", "Paul"); Person joe = createMock(Person.class); expect(friends.findByName("Joe")).andReturn(joe); expect(joe.getFriends()).andReturn(expected); replay(friends); replay(joe); assertThat("---",friendships.getFriendsList("Joe").contains("Audrey")); } }
-
EasyMock创建的不是间谍对象,而是模拟对象
-
@RestSubject类似于Mockito注解@InjectMocks,而注解@Mock类似于Mockito注解@Mock,也标注要模拟的对象,另外,type值NICE让模拟对象返回为null
-
EasyMock需要添加额外的指令replay,让前面指定的期望生效,
-
11-19
2万+
10-04