中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Spring 元測試中實現一個mock功能

發布時間:2020-12-25 14:32:33 來源:億速云 閱讀:216 作者:Leah 欄目:開發技術

這篇文章將為大家詳細講解有關怎么在Spring 元測試中實現一個mock功能,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

手動 mock

手動 mock 其實就是重新創建一個類繼承被 mock 的服務類,并重寫里面的方法。在單元測試中,利用依賴注入的方式使用 mock 的服務類替換原來的服務類。具體代碼示列如下:

/**
 * UserRepository
 *
 * @author star
 */
@Repository
public class UserRepository {

  /**
   * 模擬從數據庫中獲取用戶信息,實際開發中需要連接真實的數據庫
   */
  public User getUser(String name) {
    User user = new User();
    user.setName("testing");
    user.setEmail("testing@outlook.com");

    return user;
  }
}

/**
 * MockUserRepository
 *
 * @author star
 */
public class MockUserRepository extends UserRepository {

  /**
   * 模擬從數據庫中獲取用戶信息
   */
  @Override
  public User getUser(String name) {
    User user = new User();
    user.setName("mock-test-name");
    user.setEmail("mock-test-email");

    return user;
  }
}

// 進行單元測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceManualTest {

  @Autowired
  private UserService userService;

  @Test
  public void testGetUser_Manual() {
    // 將 MockUserRepository 注入到 UserService 中
    userService.setUserRepository(new MockUserRepository());
    User user = userService.getUser("mock-test-name");
    Assert.assertEquals("mock-test-name", user.getName());
    Assert.assertEquals("mock-test-email", user.getEmail());
  }
}

從上面的代碼中,我們可以看到手動 mock 需要編寫大量的額外代碼,同時被測試類也需要提供依賴注入的入口(setter 方法等)。如果被 mock 的類修改了函數名稱或者功能,mock 類也要跟著修改,增加了維護成本。

為了提高效率,減少維護成本,我們推薦使用單元測是框架進行 mock。

利用框架 mock

這里我們主要介紹 Mokito.mock()、@Mock、@MockBean 這三種方式的 mock。

Mocito.mock()

Mocito.mock() 方法允許我們創建類或接口的 mock 對象。然后,我們可以使用 mock 對象指定其方法的返回值,并驗證其方法是否被調用。代碼示列如下:

@Test
public void testGetUser_MockMethod() {
  // 模擬 UserRepository,測試時不直接操作數據庫
  UserRepository mockUserRepository = Mockito.mock(UserRepository.class);
  // 將 mockUserRepository 注入到 UserService 類中
  userService.setUserRepository(mockUserRepository);

  User mockUser = mockUser();
  Mockito.when(mockUserRepository.getUser(mockUser.getName()))
      .thenReturn(mockUser);

  User user = userService.getUser(mockUser.getName());
  Assert.assertEquals(mockUser.getName(), user.getName());
  Assert.assertEquals(mockUser.getEmail(), user.getEmail());

  // 驗證 mockUserRepository.getUser() 方法是否執行
  Mockito.verify(mockUserRepository).getUser(mockUser.getName());
}

@Mock

@Mock 是 Mockito.mock() 方法的簡寫。同樣,我們應該只在測試類中使用它。與 Mockito.mock() 方法不同的是,我們需要在測試期間啟用 Mockito 注解才能使用 @Mock 注解。

我們可以調用 MockitoAnnotations.initMocks(this) 靜態方法來啟用 Mockito 注解。為了避免測試之間的副作用,建議在每次測試執行之前先進行以下操作:

@Before
public void setup() {
  // 啟用 Mockito 注解
  MockitoAnnotations.initMocks(this);
}

我們還可以使用另一種方法來啟用 Mockito 注解。通過在 @RunWith() 指定 MockitoJUnitRunner 來運行測試:

@RunWith(MockitoJUnitRunner.class)
public class UserServiceMockTest { 

}

下面我們來看看如何使用 @Mock 進行服務 mock。代碼示列如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceMockTest {

  @Mock
  private UserRepository userRepository;

  @Autowired
  @InjectMocks
  private UserService userService;

  private User mockUser() {
    User user = new User();
    user.setName("mock-test-name");
    user.setEmail("mock-test-email");

    return user;
  }

  @Before
  public void setup() {
    // 啟用 Mockito 注解
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void testGetUser_MockAnnotation() {
    User mockUser = mockUser();
    Mockito.when(userRepository.getUser(mockUser.getName()))
        .thenReturn(mockUser);

    User user = userService.getUser(mockUser.getName());
    Assert.assertEquals(mockUser.getName(), user.getName());
    Assert.assertEquals(mockUser.getEmail(), user.getEmail());

    // 驗證 mockUserRepository.getUser() 方法是否執行
    Mockito.verify(userRepository).getUser(mockUser.getName());
  }

}

Mockito 的 @InjectMocks 注解作用是將 @Mock 所修飾的 mock 對象注入到指定類中替換原有的對象。

@MockBean

@MockBean 是 Spring Boot 中的注解。我們可以使用 @MockBean 將 mock 對象添加到 Spring 應用程序上下文中。該 mock 對象將替換應用程序上下文中任何現有的相同類型的 bean。如果應用程序上下文中沒有相同類型的 bean,它將使用 mock 的對象作為 bean 添加到上下文中。

@MockBean 在需要 mock 特定 bean(例如外部服務)的集成測試中很有用。

要使用 @MockBean 注解,我們必須在 @RunWith() 中指定 SpringRunner 來運行測試。代碼示列如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceMockBeanTest {

  @MockBean
  private UserRepository userRepository;

  private User mockUser() {
    User user = new User();
    user.setName("mock-test-name");
    user.setEmail("mock-test-email");

    return user;
  }

  @Test
  public void testGetUser_MockBean() {
    User mockUser = mockUser();
    // 模擬 UserRepository
    Mockito.when(userRepository.getUser(mockUser.getName()))
        .thenReturn(mockUser);
    // 驗證結果
    User user = userRepository.getUser(mockUser.getName());
    Assert.assertEquals(mockUser.getName(), user.getName());
    Assert.assertEquals(mockUser.getEmail(), user.getEmail());

    Mockito.verify(userRepository).getUser(mockUser.getName());
  }
}

這里需要注意的是,Spring test 默認會重用 bean。如果 A 測試使用 mock 對象進行測試,而 B 測試使用原有的相同類型對象進行測試,B 測試在 A 測試之后運行,那么 B 測試拿到的對象是 mock 的對象。一般這種情況是不期望的,所以需要用 @DirtiesContext 修飾上面的測試避免這個問題。

關于怎么在Spring 元測試中實現一個mock功能就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

筠连县| 鄯善县| 阳泉市| 闽侯县| 昌都县| 赤水市| 长丰县| 襄垣县| 汉寿县| 辽阳市| 隆德县| 新野县| 容城县| 南靖县| 千阳县| 肇源县| 合阳县| 顺平县| 郎溪县| 申扎县| 格尔木市| 吉安市| 汉阴县| 延吉市| 永昌县| 虹口区| 乌拉特中旗| 高碑店市| 当涂县| 逊克县| 绥中县| 清原| 甘德县| 迭部县| 通城县| 洪湖市| 仙居县| 葵青区| 蓬莱市| 和平区| 冷水江市|