Home > Back-end >  Mockito, object is not mocked
Mockito, object is not mocked

Time:04-18

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.

  1. -> at service.DishServiceTest.example(DishServiceTest.java:35)
  2. -> at service.DishServiceTest.example(DishServiceTest.java:36) 35 and 36 lines of code you can see at the screen.

enter image description here

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

  • Related