Issue
Given the following service method in a Spring Boot application:
@Transactional
public void updateCategory(long categoryId, CategoryData categoryData) {
final Category category = categoryRepository.findById(categoryId).orElseThrow(EntityNotFoundException::new);
category.setName(categoryData.getName());
}
I know how to instruct Mockito to mock the categoryRepository.findById()
result.
However, I couldn't figure out yet: Is it possible to verify that category.setName()
was called with the exact argument of categoryData.getName()
?
Solution
You are looking for Mockito.verify
, and a test looking like:
@ExtendWith(MockitoExtension.class)
public class CategoryServiceTest {
@Mock
CategoryRepository categoryRepository;
@InjectMocks
CategoryService categoryService;
@Test
public void testUpdateCategoryMarksEntityDirty() {
// given
long categoryId = 1L;
Category category = mock(Category.class);
String newCategoryName = "NewCategoryName";
when(categoryRepository.findById(categoryId)).thenReturn(Optional.of(category));
// when
categoryService.updateCategory(categoryId, new CategoryData(newCategoryName));
// then
verify(category, times(1)).setName(newCategoryName);
}
}
I must, however, advise against this style of testing.
Your code suggests that you are using a DB Access library with dirty-checking mechanism (JPA / Hibernate?). Your test focuses on the details of interaction with your DB Access layer, instead of business requirement - the update is successfully saved in the DB.
Thus, I would opt for a test against a real db, with following steps:
- given: insert a Category into your DB
- when: CategoryService.update is called
- then: subsequent calls to categoryRepository.findById return updated entity.
Answered By - Lesiak
Answer Checked By - Candace Johnson (JavaFixing Volunteer)