Here is the simple class I test. It looks strange but I have oversimplified it for a reason.
public class DishService {
DaoFactory daoFactory = DaoFactory.getInstance();
public void exampleMethod() {
System.out.println(daoFactory);
DishDao dishDao = daoFactory.createDishDao();
System.out.println(dishDao.findById(1));
}
}
And here is the DaoFactory class
public abstract class DaoFactory {
private static DaoFactory daoFactory;
public abstract UserDao createUserDao();
public abstract DishDao createDishDao();
public abstract OrderDao createOrderDao();
public static DaoFactory getInstance() {
if (daoFactory == null) {
synchronized (DaoFactory.class) {
daoFactory = new JDBCDaoFactory();
}
}
return daoFactory;
}
}
And here is my test class
@ExtendWith(MockitoExtension.class)
class DishServiceTest {
@Spy
DishService dishService;
@Mock
DishDao dishDao;
@Mock
DaoFactory daoFactory;
@Test
void example() {
MockedStatic<DaoFactory> daoFactoryDummy = Mockito.mockStatic(DaoFactory.class);
daoFactoryDummy.when(DaoFactory::getInstance).thenReturn(daoFactory);
Mockito.when(daoFactory.createDishDao()).thenReturn(dishDao);
when(dishDao.findById(1)).thenReturn(new Dish());
dishService.exampleMethod();
}
The problem is that daoFactory simply is not mocked. As you can see, I return new Dish ( default constructor ), so System.out.println()
should show an empty object but it connects to DB and fetch object from real daoFactory.
And here is what I see in console
Dish{name='dadawd', description='wdadwad2', category=DRINKS, price=23131.00, imageFileName='FIRSTSnacksAsDaypart_1.jpg', orderItems=null}
Unnecessary stubbings detected.
- -> at service.DishServiceTest.example(DishServiceTest.java:35)
- -> at service.DishServiceTest.example(DishServiceTest.java:36) 35 and 36 lines of code you can see at the screen.
CodePudding user response:
At which point do you initialize/create dishService object? In the @BeforeTest?
Since you have a field daoFactory
on dishService
object, DaoFactory.getInstance()
gets called before you mock its methods, as it is called when you create dishService
object.
So you need to create dishService object after you have mocked the Factory static methods, inside @Test method.
Or another way would be to use DaoFactory.getInstance()
directly in the dishService.exampleMethod()
.
In both cases: first mock static method, then call it.
Also don't forget to close static mock, or even better: use it inside try-with-resources construct.
Hope, this helps