Search code examples
junitautowired

mocking an autowired object and calling a method from that object


I have a class like this shown below:

public class Service {
    @Value("${value1"})
    String val1;
    
    @Value("${value2"})
    String val2;
    
    @Value("${value1"})
    String val3;
    
    @Autowired
    Client obj;
    
    public String getResponse(String location, WebRequest request) {
        // getting invocation target exception
        String id = (String)request.getAttribute(Globals.id, request.SCOPE_REQUEST);
        Point p = obj.getPoint(new Id(val1, val2, val3), "some string");
    
        // do something
        return getReply(id);
    }
}

My test class is shown below:

public class ServiceTest {
    @Mock
    WebRequest request;
    
    @Mock
    Service service;
    
    @Mock
    Client obj;
    
    @Before
    public void setup() throws Exception {
    }
    
    @Test
    public void testGetResponse() throws Exception {
        when(request.getAttribute(Matchers.anyString(), Matchers.anyInt()).thenReturn("shbchdbchd");
        when(obj.getPoint(Id.valueOf("id"), "some string").thenReturn("shbchdbchd");
        service.getResponse("some location",request);
    }

But the when(obj.getPoint) is not working, the parameters are null in the actual call in the class Service. This line

obj.getPoint(new Id(val1, val2, val3), "some string"); 

is getting null parameters.


Solution

  • It seems like you're using Spring in your Service class and no Spring in your unit test. As you're at the moment mocking all member variables in the class ServiceTest the unit test doesn't really test anything from the Service class. A solution would be to manually setup your service instance in the unit test.

    public class Service {
    //....
        @Autowired
        public Service (
            @Value("${value1"}) String value1,
            @Value("${value2"}) String value2,
            @Value("${value3"}) String value3,
            Client client
        ){
            this.val1=value1;
            this.val2=value2;
            this.val3=value3;
            this.obj=client;
        }
    //....
        public String getResponse(String location, WebRequest request) {
            // getting invocation target exception
            String id = (String)request.getAttribute(Globals.id, request.SCOPE_REQUEST);
            //should you pass id instead of val1,val2,val3?
            Point p = obj.getPoint(new Id(val1, val2, val3), "some string");
        
            // do something
            return getReply(id);
        }
    }
    
    public class ServiceTest {
        @Mock
        WebRequest request;
        
        @Mock
        Client obj;
        
        Service service;
    
        @Before
        public void setup() throws Exception {
            service = new Service("value1","value2","value3",obj);
        }
        
        @Test
        public void testGetResponse() throws Exception {
            when(request.getAttribute(Matchers.anyString(), Matchers.anyInt()).thenReturn("shbchdbchd");
            when(obj.getPoint(Id.valueOf("value1","value2","value3"), "some string").thenReturn("shbchdbchd");
    
            service.getResponse("some location",request);
        }
    

    but to me it's still unclear what you really want to test.