如何在 java 中模拟一个可选的 class?

How do I mock an optional class in java?

我在嘲笑我的 crud 应用程序,我试图嘲笑更新 API。由于 findById() 方法属于 Optional class,我找不到模拟它的方法。这是代码片段。

@Mock
@Autowired
private UserRepository repo;

@Test
public void testUpdateUser() {
    Integer userId = 3;

    Optional<User> optionalUser = repo.findById(userId);

    User user = optionalUser.get();
    user.setFirstName("Paul");
    repo.save(user);

    User updatedUser = repo.findById(userId).get();
    Assertions.assertThat(updatedUser.getFirstName()).isEqualTo("Paul");
}
@Mock
@Autowired
private UserRepository repo;

您的这部分代码可能会导致混淆。 mocking 背后的原理是创建一个 mock 对象,供您要测试的 class 使用。

您似乎想测试您的存储库。为此,您可以使用 test slice@DataJpaTest.

那么在你的情况下,你不需要模拟 optional

如果您想测试一个 Service class 或另一个使用您的 UserRepository 的 class,您将定义一个 mock 和您的 class 看起来像这样:

@Mock
private UserRepository repo;

@InjectMocks
private UserService service;

@Test
public void testUpdateUser() {

    when(repo.findById(anyInt()).get()).thenReturn(aNewInstanceOfUser());

    ...

}

更多reading.

可选 class 是最终的 class,因此您不能使用 Mockito 模拟此 class。你应该使用 PowerMockito。我在下面添加了一个示例代码。请试试这个。

@RunWith(PowerMockRunner.class)
@PrepareForTest(Optional.class)
public class PowerMockitoExample {


    @Mock
    Optional<User> optionalMock;

    @Mock Repository repo;

    @Test
    public void testUpdateUser() {
    
      //edit your mock user
      User yourUserData = null;
      
      Mockito.when(repo.findById(Matchers.anyInt())).thenReturn(optionalMock);
      PowerMockito.when(optionalMock.get()).thenReturn(yourUserData);
    
      Integer userId = 3;

      Optional<User> optionalUser = repo.findById(userId);

      User user = optionalUser.get();
      user.setFirstName("Paul");
      repo.save(user);

      User updatedUser = repo.findById(userId).get();
      Assertions.assertThat(updatedUser.getFirstName()).isEqualTo("Paul");
}

}