单元测试框架

  1. 单元测试:单元测试旨在对一小块代码进行测

  2. JUnit

    1. JUnit是一个用于编写和运行测试的框架,每个测试都是一个方法,包含特定场景下将执行的部分代码,比较预期输出和实际输出,以实现代码验证

    2. 测试类通常包含三个阶段:准备,测试和清理

    3. @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("这个方法在每个测试执行完毕后都执行");
          }
      }
      
    4. @BeforeAll指定,方法只在执行类中的测试方法前执行一次,非常适合用于执行大部分乃至全部测试都要求的一般性准备工作

    5. @BeforeEach指定,方法将在每个测试方法前运行,可使用他准备测试数据,这样就不用担心后面运行的测试修改数据状态,

    6. 这两种注解常用于准备数据库数据,创建测试所需的文件等

    7. @AfterAll指定的方法在所有测试都结束后运行一次

    8. @AfterEach指定的方法在每个测试结束后都执行

  3. Mockito

    1. 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"));
          }
      }
      
      
    2. Mockito是通过JUnit运行器运行的,他替我们创建所有必须的模拟对象,并将其注入包含测试的类,

    3. 要让一个类能够使用Mockito注解,必须使用MockitoJUnitRunner运行,@RunWith(MockitoJUnitRunner.class)

    4. 测试类中使用@InjectMocks标注受测类,以告诉Mockito应将模拟对象注入哪个类

    5. @Mock需要指定将Friendships中哪些方法或对象替换为模拟对象,将模拟Friendships这个类中的FriendsCollection对象

    6. Mockito Spy的主要特点包括:

      1. 部分模拟:Spy对象可以在真实对象的基础上进行部分模拟,只模拟我们感兴趣的方法,而其他方法将保持原样。
      2. 保留真实行为:Spy对象会保留真实对象的行为,除非我们显式地指定了模拟行为。这使得我们可以在需要时调用真实对象的方法。
      3. 验证方法调用:与其他Mockito功能一样,我们可以使用Spy对象来验证方法的调用次数、参数等。
    7. Mockito Spy的应用场景包括:

      1. 测试私有方法:Spy对象可以用于测试私有方法,通过部分模拟真实对象,我们可以调用私有方法并验证其行为。
      2. 测试依赖关系:当我们需要测试一个对象,但它依赖于其他对象时,我们可以使用Spy对象来模拟这些依赖关系的行为。
      3. 测试异常情况:通过Spy对象,我们可以模拟真实对象的异常情况,以测试代码在异常情况下的行为。
  4. EasyMock

    1. 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"));
          }
      }
      
      
    2. EasyMock创建的不是间谍对象,而是模拟对象

    3. @RestSubject类似于Mockito注解@InjectMocks,而注解@Mock类似于Mockito注解@Mock,也标注要模拟的对象,另外,type值NICE让模拟对象返回为null

    4. EasyMock需要添加额外的指令replay,让前面指定的期望生效,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值