【问题标题】:Mockito how to test findById() returning an OptionalMockito 如何测试 findById() 返回一个 Optional
【发布时间】:2019-11-03 16:35:07
【问题描述】:

我一直在尝试从 CrudRepository 测试 findById() 方法。 这个方法返回一个Optional,我不知道如何返回它, 现在它给了我一个NullPointerException

我的测试代码如下:

@RunWith(MockitoJUnitRunner.class)
public class DishServiceMockTest {

    private static final String DISH_NAME = "Kaas";
    private static final String DISH_TYPE = "Voorgerecht";
    private static final Long DISH_ID = 23L;

    //Mock the service dependencies(=DishServiceImpl is dependent on dishRepo)
    @Mock
    DishRepository dishRepository;

    //Mock the service which is to be tested (Can't be a interface)
    @InjectMocks
    DishServiceImpl dishService;

@Test
public void findById(){
    //Arange
    Dish dish = createDish(DISH_ID, DISH_NAME, DISH_TYPE);

    Mockito.when(dishRepository.findById(DISH_ID)).thenReturn(Optional.of(dish));
    assertThat(dishService.findById(DISH_ID)).isEqualTo(dish);

}

运行测试给了我 2 个错误,其中一个是 NullPointerException,第二个是:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at avans.ivh11.proftaak.mocks.DishServiceMockTest.findById(DishServiceMockTest.java:85)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, which is not supported
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

NPE

java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Optional.<init>(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
at avans.ivh11.proftaak.mocks.DishServiceMockTest.findById(DishServiceMockTest.java:85)

比较失败

org.junit.ComparisonFailure: 
Expected :avans.ivh11.proftaak.Domain.Dish@17
Actual   :Optional[avans.ivh11.proftaak.Domain.Dish@17]

【问题讨论】:

  • 为什么选择 NPE?它在哪里?代码接缝对我来说是合法的。
  • 我添加了 NPE 错误代码
  • 您确定您输入到Optional.of() 中的dish 不为空吗?
  • 我的 createDish() 方法中有一个 discService.save() 方法。制作一个新的 Dish 手动修复了 NPE,但现在它给了我一个 ComparisionFailure,我将它添加到我的原始帖子中。编辑:添加 isEqualTo(Optional.of(dish));修复。感谢您的帮助!
  • NPE 自己说 - 菜是空的。

标签: java spring-boot spring-mvc junit mockito


【解决方案1】:

这个堆栈跟踪

java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Optional.<init>(Optional.java:96)
at java.util.Optional.of(Optional.java:108)
at avans.ivh11.proftaak.mocks.DishServiceMockTest.findById(DishServiceMockTest.java:85)

dishfrom .thenReturn(Optional.of(dish));是null。仔细检查您的 createDish 方法。

第二个异常是第一个异常的结果

 Mockito.when(dishRepository.findById(DISH_ID)).thenReturn(Optional.of(dish));

when 已成功调用,但要调用 thenReturn Optiona.of 必须进行评估 - 调用失败,因此从未进行过 thenReturn 调用。

实际上这不是“运行时”异常,而是测试后异常。

【讨论】:

  • NullPointerException 确实是由我的 createDish 方法中不必要的 discService.save(dish) 调用引起的,删除这个修复了 NPE。我之后遇到的 ComparisonFailure 错误已通过使用 assertThat(dishService.findById(DISH_ID)).isEqualTo(Optional.of(dish)); 修复;
【解决方案2】:

使用 doReturn(Optional.of(yourMockObj)).when(employeeRepository).findById(idToFind);

示例代码

@Test
@Order(2)
@DisplayName("Test getEmployeeByEmployeeId")
public void test_getEmployeeByEmployeeId() throws EmployeeNotFoundException
{
    // Setup the mock repo
    Long employeeId = 1L;
    Employee e1ForMock = new Employee(employeeId, "Aravinth P", 29, "aravinth.p@email.com");
    doReturn(Optional.of(e1ForMock)).when(employeeRepository).findById(employeeId);
    // Make the service call
    Employee e1ByService = employeeServiceImpl.getEmployeeByEmployeeId(employeeId);
    // Assert the response
    assertNotNull(e1ByService,"Employee with employeeId : "+employeeId+" not found");
    assertEquals(employeeId,e1ByService.getEmployeeId());
    assertEquals(e1ForMock.getName(), e1ByService.getName());
    assertEquals(e1ForMock.getAge(), e1ByService.getAge());
    assertEquals(e1ForMock.getEmail(), e1ByService.getEmail());
}

【讨论】:

    猜你喜欢
    • 2020-06-23
    • 1970-01-01
    • 2021-04-25
    • 1970-01-01
    • 2019-07-20
    • 2020-09-10
    • 2022-01-06
    • 2021-12-16
    • 2015-09-05
    相关资源
    最近更新 更多