I am trying to mock the behavior of a method that is called inside another so that it simulates the return of an object and another time it raises an exception but not if exactly if it is possible and if it is how it would be possible.
#Service
#Transactional
public class CategoryService {
#Autowired
private CategoryRepository repository;
public Category findById(Integer id) {
Optional<Category> obj = repository.findById(id);
return obj.orElseThrow(() -> new ObjectNotFoundException(id.toString()));
}
public Category update(Category category){
// Throws ObjectNotFoundException if not found before update
this.findById(category.getId());
return repository.save(category);
}
}
#RunWith(MockitoJUnitRunner.class)
public class CategoryServiceUnitTest {
#Mock
private CategoryService service;
#Test()
public void Should_UpdateCategory_When_FindCategory() {
Category cat = new Category(1, "Test");
//Is it possible?
when(service.findById(Mockito.anyInt())).thenReturn(cat);
Category category = service.update(cat);
assertThat(category.getName()).isEqualTo(cat.getName());
verify(service, times(1)).update(cat);
}
#Test(expected = ObjectNotFoundException.class)
public void Should_ThrowsObjectNotFoundException_When_NotFoudCategoryById() {
Category cat = new Category(1, "Test");
//Is it possible?
when(service.findById(Mockito.anyInt())).thenThrow(ObjectNotFoundException.class);
service.update(cat);
}
}
As pointed out in the comments, what you want to do is mock CategoryRepository in your test.
#RunWith(MockitoJUnitRunner.class)
public class CategoryServiceTest {
private CategoryService service;
#Mock
private CategoryRepository repository;
#Before
public void setup() {
service = spy(new CategoryService(repository));
}
#Test
public void Should_UpdateCategory_When_FindCategory() throws ObjectNotFoundException {
Category cat = new Category(1, "Test");
when(repository.findById(Mockito.anyLong())).thenReturn(Optional.of(cat));
//return the category object that is used to call the repository.save(...) method
when(repository.save(Mockito.any(Category.class)))
.thenAnswer((Answer<Category>) invocation -> {
Object[] args = invocation.getArguments();
return (Category) args[0];
}
);
//depending on your requirements the above might be overkill, just replace that logic with this
//when(repository.save(Mockito.any(Category.class))).thenReturn(cat);
Category category = service.update(cat);
assertThat(category).isNotNull();
assertThat(category.getName()).isEqualTo(cat.getName());
verify(service).update(cat);
}
#Test(expected = ObjectNotFoundException.class)
public void Should_ThrowsObjectNotFoundException_When_NotFoudCategoryById() throws ObjectNotFoundException {
Category cat = new Category(1, "Test");
when(service.findById(Mockito.anyLong())).thenThrow(ObjectNotFoundException.class);
service.update(cat);
}
}
You'll also need to handle the checked exception ObjectNotFoundException. I just added the exception to the method signature, you might want to handle it differently in a production setting
#Service
#Transactional
public class CategoryService {
private final CategoryRepository repository;
#Autowired
public CategoryService(CategoryRepository repository) {
this.repository = repository;
}
public Category findById(Long id) throws ObjectNotFoundException {
Optional<Category> obj = repository.findById(id);
return obj.orElseThrow(() -> new ObjectNotFoundException(id.toString()));
}
public Category update(Category category) throws ObjectNotFoundException {
// Throws ObjectNotFoundException if not found before update
this.findById(category.getId());
return repository.save(category);
}
}
Related
I have this method to update a table in DB, it works correctly, until I create the unit test for it:
public class ReferentialAdapter {
private final JPAQueryFactory queryFactory;
public void enableServiceConfigs(String roleCode, String countryIsoCode, List<String> services) {
QServiceConfigEntity qServiceConfigEntity = QServiceConfigEntity.serviceConfigEntity;
QCountryRoleEntity qCountryRoleEntity = QCountryRoleEntity.countryRoleEntity;
QServiceEntity qServiceEntity = QServiceEntity.serviceEntity;
JPQLQuery<Long> countryRoleId = JPAExpressions.select(qCountryRoleEntity.id).from(qCountryRoleEntity)
.where(qCountryRoleEntity.country.isoCode.equalsIgnoreCase(countryIsoCode).and(qCountryRoleEntity.role.code.equalsIgnoreCase(roleCode)));
BooleanExpression whereCondition = qServiceConfigEntity.countryRole.id.eq(countryRoleId)
.and(qServiceConfigEntity.service.id.in(serviceIds));
queryFactory.update(qServiceConfigEntity)
.where(whereCondition)
.set(qServiceConfigEntity.isEnabled, Boolean.TRUE)
.execute();
}
}
configuration for JPAQueryFactory:
#Configuration
public class QueryDslConfig {
#PersistenceContext
private EntityManager entityManager;
#Bean
public JPAQueryFactory jpaQueryFactory() {
return new JPAQueryFactory(entityManager);
}
}
but this test throw a null pointer exception when call the execute() for the update.
#ExtendWith(MockitoExtension.class)
class ReferentialAdapterTest {
#Mock
private JPAQueryFactory queryFactory;
#InjectMocks
private ReferentialAdapter referentialAdapter;
#Test
void shouldEnableServicesConfig() {
String roleCode = "CA_ICS_HBE";
String countryIsoCode= "FR";
List<String> services = Arrays.asList("VT" , "CAF");
referentialAdapter.enableServiceConfigs(roleCode,countryIsoCode,services);
verify(queryFactory,times(1)).update(any());
}
}
i want to mock a void method in the same class that is under test with mockito.
i can do that for not void method with annotating test class with #Spy and then use below code to return data i want.
willAnswer(arg -> arg.getArgument(0))
.given(customerService)
.saveCustomer(any(Customer.class));
but how can do that for void method.
(i already try willDoNothing().given() function)
this is my real method:
public void deleteCustomersByTenantId(TenantId tenantId) throws ThingsboardException {
log.trace("Executing deleteCustomersByTenantId, tenantId [{}]", tenantId);
Validator.validateId(tenantId, "Incorrect tenantId " + tenantId);
customersByTenantRemover.removeEntities(tenantId, tenantId);
}
public void deleteCustomer(TenantId tenantId, CustomerId customerId) throws ThingsboardException {
log.trace("Executing deleteCustomer [{}]", customerId);
Validator.validateId(customerId, INCORRECT_CUSTOMER_ID + customerId);
Customer customer = findCustomerById(tenantId, customerId);
if (customer == null) {
throw new IncorrectParameterException("Unable to delete non-existent customer.");
}
entityViewService.unassignCustomerEntityViews(customer.getTenantId(), customerId);
assetService.unassignCustomerAssets(customer.getTenantId(), customerId);
userService.deleteCustomerUsers(customer.getTenantId(), customerId);
deleteEntityRelations(tenantId, customerId);
entityGroupDao.deleteEntityGroupsByTenantIdAndCustomerId(customer.getTenantId(), customerId);
customerDao.removeById(tenantId, customerId.getId());
}
private final PaginatedRemover<TenantId, Customer> customersByTenantRemover =
new PaginatedRemover<>() {
#Override
protected PageData<Customer> findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return customerDao.findCustomersByTenantId(id.getId(), pageLink);
}
#Override
protected void removeEntity(TenantId tenantId, Customer entity) throws ThingsboardException {
deleteCustomer(tenantId, new CustomerId(entity.getUuidId()));
}
};
and this is the test:
void deleteCustomersByTenantId() throws ThingsboardException {
//given
Customer customer = new Customer();
customer.setId(CUSTOMER_ID);
customer.setTenantId(TENANT_ID);
ArgumentCaptor<CustomerId> customerIdArgumentCaptor = ArgumentCaptor.forClass(CustomerId.class);
var pageData = new PageData<>(Collections.singletonList(customer), 1 ,1 , false);
given(customerDao.findCustomersByTenantId(any(UUID.class), any(PageLink.class)))
.willReturn(pageData);
doNothing()
.when(customerService)
.deleteCustomer(any(), any());
//when
customerService.deleteCustomersByTenantId(TENANT_ID);
//then
then(customerDao)
.should(times(1))
.findCustomersByTenantId(any(UUID.class), any(PageLink.class));
then(customerService)
.should(times(1))
.deleteCustomer(any(TenantId.class), customerIdArgumentCaptor.capture());
assertEquals(CUSTOMER_ID, customerIdArgumentCaptor.getValue());
}
this is the Mocks:
//other mocks...
#Mock
private RelationService relationService;
#Mock
private CustomerValidator customerValidator;
#InjectMocks
#Spy
private CustomerServiceImpl customerService;
every dependency is mock with #Mock.
Do nothing works for me. Just pay attention to the calling order
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
doNothing().when(yourMock).yourMethod(yourArgs);
This thread treats a similar problem, using a spy to mock specific methods with static factories should work. I've seen people doing to reverse operation (Use a Mock and then call the real method in some specific cases), but never tried it personally..
I'm having trouble figuring out why Mockito is throwing a NullPointerException when I'm telling the mock to return true.
Here is my JUnit Test:
public class PizzaValidatorTest {
private Pizza meatPizza;
private PizzaValidator validator = new PizzaValidator();
#MockBean
private IngredientRepository ingredientRepository;
#MockBean
private PizzaSizeRepository pizzaSizeRepository;
#Before
public void setUp() throws Exception {
meatPizza = new Pizza();
validator = new PizzaValidator();
}
#Test
public void validateValid() {
when(ingredientRepository.existsById(any())).thenReturn(true);
when(pizzaSizeRepository.existsById(any())).thenReturn(true);
assertTrue(validator.validate(meatPizza));
}
}
The PizzaValidator class is implemented below:
#Controller
public class PizzaValidator implements Validator<Pizza> {
#Autowired
IngredientRepository ingredientRepository;
#Autowired
PizzaSizeRepository pizzaSizeRepository;
#Override
public boolean validate(Pizza entity) {
return validatePizza(entity);
}
private boolean validatePizza(Pizza pizza) {
return validPizzaSize(pizza) && validIngredients(pizza);
}
private boolean validPizzaSize(Pizza pizza) {
return pizzaSizeRepository.existsById(pizza.getSizeDesc().getId());
}
private boolean validIngredients(Pizza pizza) {
for (Ingredient ingredient : pizza.getIngredients()) {
if (!ingredientRepository.existsById(ingredient.getId())) {
return false;
}
}
return true;
}
}
For some reason it seems like Mockito isn't connecting the mock repository with my class repository, but I can't figure out why. Any help is appreciated. Thanks.
You should not create the PizzaValidator using new keyword, you should #Autowire it in the test
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest
public class PizzaValidatorTest {
private Pizza meatPizza;
#Autowire
private PizzaValidator validator;
#MockBean
private IngredientRepository ingredientRepository;
#MockBean
private PizzaSizeRepository pizzaSizeRepository;
#Before
public void setUp() throws Exception {
meatPizza = new Pizza();
}
#Test
public void validateValid() {
when(ingredientRepository.existsById(any())).thenReturn(true);
when(pizzaSizeRepository.existsById(any())).thenReturn(true);
assertTrue(validator.validate(meatPizza));
}
}
I'm writing integration tests for a spring web app and I have reached a step where I need to mock service methods calls which have a void return type. I've done some research on some ways to do this but none seem to be the correct way.
What I want to do is:
When the save() method is called on recipeService, it should save the recipe
Below I'll provide the code and also the two main ways I've tried already. If anyone can help that would be great!
The method that needs mocking
#RequestMapping(path = "/recipes/add", method = RequestMethod.POST)
public String persistRecipe(#Valid Recipe recipe, BindingResult result, #RequestParam("image") MultipartFile photo, RedirectAttributes redirectAttributes) {
if (result.hasErrors()) {
redirectAttributes.addFlashAttribute("recipe", recipe);
redirectAttributes.addFlashAttribute("flash",
new FlashMessage("I think you missed something. Try again!", FlashMessage.Status.FAILURE));
return "redirect:/recipes/add";
}
User user = getUser();
recipe.setOwner(user);
user.addFavorite(recipe);
recipeService.save(recipe, photo);
userService.save(user);
redirectAttributes.addFlashAttribute("flash", new FlashMessage("The recipe has successfully been created", FlashMessage.Status.SUCCESS));
return "redirect:/recipes";
}
The service that needs calling (save method)
#Service
public class RecipeServiceImpl implements RecipeService {
private final RecipeRepository recipes;
#Autowired
public RecipeServiceImpl(RecipeRepository recipes) {
this.recipes = recipes;
}
#Override
public void save(Recipe recipe, byte[] photo) {
recipe.setPhoto(photo);
recipes.save(recipe);
}
#Override
public void save(Recipe recipe, MultipartFile photo) {
try {
recipe.setPhoto(photo.getBytes());
recipes.save(recipe);
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Recipe findById(Long id) {
Optional<Recipe> recipe = recipes.findById(id);
if (recipe.isPresent()) {
return recipe.get();
}
// TODO:drt - Create new exception to handle this
throw new RuntimeException();
}
#Override
public Recipe findByName(String name) {
return null;
}
#Override
public List<Recipe> findAll() {
return (List<Recipe>) recipes.findAll();
}
#Override
public void deleteById(Long id) {
recipes.deleteById(id);
}
}
Attempt 1
#Test
#WithMockUser(value = "daniel")
public void createNewRecipeRedirects() throws Exception {
User user = userBuilder();
Recipe recipe = recipeBuilder(1L);
recipe.setOwner(user);
user.addFavorite(recipe);
MockMultipartFile photo = new MockMultipartFile("image", "food.jpeg",
"image/png", "test image".getBytes());
when(userService.findByUsername("daniel")).thenReturn(user);
doAnswer(new Answer<Void>() {
#Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments != null && arguments.length > 1 && arguments[0] != null && arguments[1] != null) {
Recipe recipe1 = (Recipe) arguments[0];
MultipartFile file = (MultipartFile) arguments[1];
recipe1.setPhoto(file.getBytes());
}
return null;
}
}).when(recipeService).save(any(Recipe.class), any(MultipartFile.class));
mockMvc.perform(post("/recipes/add"))
.andExpect(redirectedUrl("/recipes"))
.andExpect(flash().attributeExists("flash"));
}
Attempt 2
#Test
#WithMockUser(value = "daniel")
public void createNewRecipeRedirects() throws Exception {
List<Recipe> recipes = recipeListBuilder();
List<User> users = new ArrayList<>();
User user = userBuilder();
Recipe recipe = recipeBuilder(1L);
recipe.setOwner(user);
user.addFavorite(recipe);
MockMultipartFile photo = new MockMultipartFile("image", "food.jpeg",
"image/png", "test image".getBytes());
when(userService.findByUsername("daniel")).thenReturn(user);
doAnswer(answer -> {
recipe.setPhoto(photo.getBytes());
recipes.add(recipe);
return true;
}).when(recipeService).save(any(Recipe.class), any(MultipartFile.class));
doAnswer(answer -> {
users.add(user);
return true;
}).when(userService).save(any(User.class));
mockMvc.perform(post("/recipes/add"))
.andExpect(redirectedUrl("/recipes"))
.andExpect(flash().attributeExists("flash"));
assertEquals(3, recipes.size());
assertEquals(1, users.size());
}
Complete test code so far
#RunWith(SpringRunner.class)
#SpringBootTest(classes = Application.class)
#WebAppConfiguration
public class RecipeControllerTests {
private MockMvc mockMvc;
#Mock
private RecipeService recipeService;
#Mock
private UserService userService;
#Mock
private IngredientService ingredientService;
#Autowired
WebApplicationContext wac;
#InjectMocks
private RecipeController recipeController;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.webAppContextSetup(wac).apply(springSecurity()).build();
}
/**
* Tests for index pages / & /recipes
*/
#Test
#WithUserDetails(value = "daniel")
public void indexPageLoads() throws Exception {
List<Recipe> recipes = recipeListBuilder();
List<Ingredient> ingredients = ingredientsListBuilder();
when(recipeService.findAll()).thenReturn(recipes);
when(ingredientService.findAll()).thenReturn(ingredients);
when(userService.findByUsername("daniel")).thenReturn(userBuilder());
mockMvc.perform(get("/recipes"))
.andExpect(model().attributeExists("recipes", "ingredients", "favs"))
.andExpect(status().isOk());
}
/**
* Tests for page /recipes/add
*/
#Test
#WithMockUser
public void addRecipePageLoads() throws Exception {
mockMvc.perform(get("/recipes/add"))
.andExpect(model().attributeExists("task", "buttonAction", "action", "photo", "recipe"))
.andExpect(status().isOk());
}
#Test
#WithUserDetails("daniel")
public void createNewRecipeRedirects() throws Exception {
User user = userBuilder();
Recipe recipe = recipeBuilder(1L);
recipe.setOwner(user);
user.addFavorite(recipe);
MultipartFile photo = new MockMultipartFile("image", "food.jpeg",
"image/jpeg", "dummy content file".getBytes());
when(userService.findByUsername("daniel")).thenReturn(user);
verify(recipeService, times(1)).save(recipe, photo);
verify(userService, times(1)).save(user);
mockMvc.perform(post("/recipes/add"))
.andExpect(redirectedUrl("/recipes"))
.andExpect(flash().attributeExists("flash"));
}
private User userBuilder() {
User user = new User();
user.setFavorites(recipeListBuilder());
user.setId(1L);
user.setRoles(new String[]{"ROLE_USER", "ROLE_ADMIN"});
user.setUsername("daniel");
user.setPassword("password");
return user;
}
private List<Recipe> recipeListBuilder() {
List<Recipe> recipes = new ArrayList<>();
recipes.add(recipeBuilder(1L));
recipes.add(recipeBuilder(2L));
return recipes;
}
private List<Ingredient> ingredientsListBuilder() {
List<Ingredient> ingredients = new ArrayList<>();
ingredients.add(ingredientBuilder());
return ingredients;
}
private Ingredient ingredientBuilder() {
Ingredient ingredient = new Ingredient();
ingredient.setCondition("good");
ingredient.setName("test ing");
ingredient.setQuantity(1);
ingredient.setId(1L);
return ingredient;
}
private Recipe recipeBuilder(Long id) {
Recipe recipe = new Recipe();
recipe.setName("Test recipe");
recipe.setDescription("Test Description");
recipe.setId(id);
recipe.setCategory(Category.ALL_CATEGORIES);
recipe.setCookTime(10);
recipe.setPrepTime(10);
recipe.addIngredient(ingredientBuilder());
return recipe;
}
}
try Mockito.doNothing(): it basically tells Mockito to do nothing when a method in a mock object is called:
Mockito.doNothing().when(recipeService).save(any(Recipe.class), any(MultipartFile.class));
If you are mocking the save method I would use one of the ‘do...‘
Docs
Of course this suggests your method has a side effect somewhere.
If you want to ensure a method is called the you can use ‘verify‘ as mentioned in other answers.
Generally speaking mocking allows you to replace some collaboration/functionality with a version which is under the tests control where as verifying allows for checking something occurred (or didn’t)
If you have some logic that you want to unit test and this logic invokes methods of other component that you want to mock and some of those methods return void - the typical way of testing your logic is to verify that your logic actually invoked the void methods of mocked object. You can achieve this by using Mockito::verify :
Mockito.verify(recipeService, Mockito.times(1)).save(any(Recipe.class), any(MultipartFile.class));
This way you test that logic of persistRecipe() method actually invoked the desired method on your mock object.
I have a junit test method as follows:
#SpringBootTest
public class StoreIdAssignmentServiceTest {
private static final Logger log = LoggerFactory
.getLogger(StoreIdAssignmentServiceTest.class);
#InjectMocks
private StoreIdAssignmentService storeIdAssignmentService;
#Mock
private StoreIdAssignmentFactory storeIdAssignmentFactory;
#Mock
private DatabaseService databaseService;
#Test
public void rollUpFeed_Single_DealerAndStoreID_NoExisting() {
List<ScmsaPosTransRollup> scmsaPosTransRollupFeedList = new ArrayList<>();
ScmsaPosTransRollup posTransRollup = new ScmsaPosTransRollup();
posTransRollup.setJobLogId(8269726L);
posTransRollup.setDealerCode("3119255");
posTransRollup.setStoreId("9842");
posTransRollup.setTransactionDate(Timestamp
.valueOf("2018-03-01 13:00:00.00"));
posTransRollup.setQuantity(4);
posTransRollup.setRollupType("H");
scmsaPosTransRollupFeedList.add(posTransRollup);
Mockito.when(
databaseService.getUnProcessedRollUpFeedBasedonRollupType("H"))
.thenReturn(scmsaPosTransRollupFeedList);
List<PosHourlySt> existingPosHourlyStEntries = new ArrayList<>();
Mockito.when(databaseService.getDealerCodeFromPosHourly("3119255"))
.thenReturn(existingPosHourlyStEntries);
Mockito.when(databaseService.getDealerCodeFromPosHourly("3119255"))
.thenReturn(existingPosHourlyStEntries);
storeIdAssignmentService.processHourlyStateFeed();
assertNotNull(posHourlyStRepository.findAll());
}
}
And My StoreIdAssignmentService class will be:
#Service
public class StoreIdAssignmentService {
private StoreIdAssignmentFactory storeIdAssignmentFactory;
private DatabaseService databaseService;
#Autowired
public StoreIdAssignmentService(StoreIdAssignmentFactory storeIdAssignmentFactory,
DatabaseService databaseService) {
this.storeIdAssignmentFactory = storeIdAssignmentFactory;
this.databaseService = databaseService;
}
public void processHourlyStateFeed() {
.......................
calculateStateForPosHourlyStTransaction(posHourlyStToConsider, newPosHourlyStEntries);
.........
}
List<ScmsaPosTransRollup> scmsaPosTransRollupUpdatedFlagList = storeIdAssignmentFactory
.createUpdatedRollUpEntries(rollUpFeedByDealerCode);
saveAndUpdatePosHourlyStAndRollUpEntries(newPosHourlyStEntries, existingPosHourlyStEntries,
rollUpFeedByDealerCode, scmsaPosTransRollupUpdatedFlagList);
}
}
private Map<String, List<ScmsaPosTransRollup>> groupDealerCodeRollUpFeedByStoreId(
List<ScmsaPosTransRollup> rollUpFeedByDealerCode) {
// Grouping the rollUpFeedByDealerCode by storeID
return rollUpFeedByDealerCode.stream().collect(Collectors.groupingBy(ScmsaPosTransRollup::getStoreId));
}
private void calculateStateForPosHourlyStTransaction(ScmsaPosTransRollup scmsaPosTransRollupToConsider, List<PosHourlySt> newPosHourlyStEntries) {
List<PosHourlySt> posHourlyStList = newPosHourlyStEntries.stream().filter(
hourlyState -> (hourlyState.getStartDate().before(scmsaPosTransRollupToConsider.getTransactionDate())))
.collect(Collectors.toList());
..............
PosHourlySt posHourlySt=storeIdAssignmentFactory.createHourlyStEntryFromRollUp(scmsaPosTransRollupToConsider,
Timestamp.valueOf(scmsaPosTransRollupToConsider.getTransactionDate().toLocalDateTime().withHour(0).withMinute(0)),
Timestamp.valueOf(scmsaPosTransRollupToConsider.getTransactionDate().toLocalDateTime().withHour(23).withMinute(59)));
newPosHourlyStEntries.add(posHourlySt);
....................
}
}
and My Factory class would be:
#Component
public class StoreIdAssignmentFactory {
private static final Logger log = LoggerFactory.getLogger(StoreIdAssignmentFactory.class);
private ModelMapper modelMapper;
#Autowired
public StoreIdAssignmentFactory(ModelMapper modelMapper) {
this.modelMapper = modelMapper;
}
public PosHourlySt createHourlyStEntryFromRollUp(ScmsaPosTransRollup scmsaPosTransRollup, Timestamp startDate, Timestamp endDate){
PosHourlySt posHourlySt = new PosHourlySt();
posHourlySt.setDealerCode(scmsaPosTransRollup.getDealerCode());
posHourlySt.setSourceJobLogId(scmsaPosTransRollup.getJobLogId());
posHourlySt.setStartDate(startDate);
posHourlySt.setStoreId(scmsaPosTransRollup.getStoreId());
posHourlySt.setEndDate(endDate);
posHourlySt.setJobLogId(0L);
posHourlySt.setSource("ROLLUP");
log.info("New Rec: {}", posHourlySt.toString());
return posHourlySt;
}
public PosHourlySt createHourlyStEntryFromPosHourlySt(PosHourlySt posHourlyStToSplit, Timestamp endDate){
PosHourlySt posHourlySt = new PosHourlySt();
posHourlySt.setDealerCode(posHourlyStToSplit.getDealerCode());
posHourlySt.setSourceJobLogId(posHourlyStToSplit.getJobLogId());
posHourlySt.setStartDate(posHourlyStToSplit.getStartDate());
posHourlySt.setStoreId(posHourlyStToSplit.getStoreId());
posHourlySt.setEndDate(endDate);
posHourlySt.setJobLogId(0L);
posHourlySt.setSource("ROLLUP");
log.info("SplitupRec: {}", posHourlySt.toString());
return posHourlySt;
}
public List<ScmsaPosTransRollup> createUpdatedRollUpEntries(List<ScmsaPosTransRollup> rollUpFeedByDealerCode) {
List<ScmsaPosTransRollup> scmsaPosTransRollupUpdatedFlagList = new ArrayList<>();
for(ScmsaPosTransRollup scmsaPosTransRollupFeed : rollUpFeedByDealerCode) {
ScmsaPosTransRollup scmsaPosTransRollupUpdateFlag = new ScmsaPosTransRollup();
modelMapper.map(scmsaPosTransRollupFeed, scmsaPosTransRollupUpdateFlag);
scmsaPosTransRollupUpdateFlag.setProcessedFlag("Y");
scmsaPosTransRollupUpdatedFlagList.add(scmsaPosTransRollupUpdateFlag);
}
return scmsaPosTransRollupUpdatedFlagList;
}
}
The StoreIdAssignmentService class contains the method "calculateStateForPosHourlyStTransaction" which calls some method in Factory class. When I debug as the junit test case , am not able to call that factory class method . What I am doing wrong here. Can anyone please suggest me.
You are mocking the factory:
#Mock
private StoreIdAssignmentFactory storeIdAssignmentFactory;
So you can't investigate the method createHourlyStEntryFromRollUp inside the factory, because the whole factory is mocked:
storeIdAssignmentFactory.createHourlyStEntryFromRollUp
If you trying to debug the createHourlyStEntryFromRollUp and the StoreIdAssignmentFactory is a #Component (or #Service), I recommend create a StoreIdAssignmentFactoryTest class test, use the #Autowired on it and #MockBean his dependencies.
Example:
#SpringBootTest
public class StoreIdAssignmentFactoryTest {
#Autowired
StoreIdAssignmentFactory factory;
#Test
public void testing() {
List<ScmsaPosTransRollup> list = factory.createHourlyStEntryFromRollUp(...);
//TODO asserts and etc
}
}
But this test is considered a integration test, because it load the whole spring context and beans related.
Another alternative is the (true) unit test. Use your constructor and not use #SpringBootTest, mock the dependencies (ModelMapper). This makes the test more fast and simple.
Example:
public class StoreIdAssignmentFactoryTest {
#Test
public void testing() {
ModelMapper mapper = mock(ModelMapper.class);
StoreIdAssignmentFactory factory = new StoreIdAssignmentFactory(mapper)
List<ScmsaPosTransRollup> list = factory.createHourlyStEntryFromRollUp();
//TODO asserts and etc
}
}