Spring test service class mocking utility class- Junit and Mockito

17,740

Solution 1

You have to first mock the Utility class and then have to invoke it before calling your @Test using MockitoAnnotations.initMocks(this) as follows:

MyServiceTest.java

import static org.mockito.Mockito.when;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.AnnotationConfigWebContextLoader;
import org.springframework.test.context.web.WebAppConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class)
@WebAppConfiguration
public class MyServiceTest {

    @InjectMocks
    private MyService myService;

    @Mock
    private Utility utility;

    @Before
    public void setupMock() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testShowResult() throws Exception {
        when(utility.getName()).thenReturn("Test");
        Assert.assertEquals("Test", myService.showResult());
    }

    @Configuration
    static class MykServiceTestContextConfiguration {

        @Bean
        public MyService myService() {
            return new MyService();
        }

        @Bean
        public Utility utility() {
            return new Utility();
        }
    }

}

MyService.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Autowired
    private Utility utility;

    public String showResult() {
        String result = utility.getName();
        return result;
    }
}

Utility.java

import org.springframework.stereotype.Component;

@Component
public class Utility {
    public String getName() {
        return "hello";
    }

}

Solution 2

Make use of @Spy

When spy is called, then actual method of real object is called.

https://www.tutorialspoint.com/mockito/mockito_spying.htm

please go through the tutorial

This worked for me

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class MyServiceTest {

    @Spy
    MyService myService;  


    @Test
    public void testShowResult() throws Exception {

        assertEquals("Test",myService.showResult());

    }    

    @Service
    public class MyService{


        public String showResult(){  
            return "Test";
        }
    }

}

still having issues share the spring version you are using

Solution 3

How about using @MockBean? It suits Spring + JUnit and, probably you need to implement mock behavior.

I guess that Utility.getName() return "Test" in the test case.

The following is the test code I tried.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigWebContextLoader.class)
@WebAppConfiguration
public class MyServiceTest {

    @Autowired
    MyService myService;

    @MockBean
    Utility utility;

    @Test
    public void testShowResult() throws Exception {
        Mockito.when(utility.getName()).thenReturn("Test");

        assertEquals("Test", myService.showResult());
    }

    @Configuration
    static class MykServiceTestContextConfiguration {

        @Bean
        public MyService myService() {
            return new MyService();
        }
    }
}
Share:
17,740
Bhabani Sankar Sahoo
Author by

Bhabani Sankar Sahoo

Updated on June 04, 2022

Comments

  • Bhabani Sankar Sahoo
    Bhabani Sankar Sahoo almost 2 years

    I want to write test cases for service layer of spring framework using Junit + Mockito.

    How to call the actual service layer method using my ServiceTest class, If i mock the ServiceTest class then it's object wont execute the actual service method code because it wont get the object to call it's methods and if I try with the Spy still it was not working, I tried this example still I not able to execute the test cases.

    MyService.java

    @Service
     public class MyService{
    
        @Autowired
        Utility utility;
    
        public String showResult(){
    
        String result = utility.getName();
    
        return result;
        }
        }
    

    MyServiceTest.java

        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration(loader=AnnotationConfigWebContextLoader.class)
        @WebAppConfiguration
        public class MyServiceTest {
    
            @Autowired
            MyService myService;
    
    
            @Autowired
            Utility utility; 
    
    
    
    
            @Test
            public void testShowResult() throws Exception {
    
                assertEquals("Test",myService.showResult());
    
            }
    
            @Configuration
            static class MykServiceTestContextConfiguration {
    
                @Bean
                public MyService myService() {
                    return new MyService();
                }           
    
                @Bean
                public Utility utility() {
                    return Mockito.mock(Utility.class);
                }
            }
    
        }
    
    • pringi
      pringi over 7 years
      Missing @Component in MyService and Utility classes
  • Bhabani Sankar Sahoo
    Bhabani Sankar Sahoo over 7 years
    I added the @Mock Utility utility;` @InjectMocks` private MyService myService; i deleted the static inner class then it worked for me , Thanks for the help Arpit