模拟一个自动装配的对象并从该对象调用一个方法

mocking an autowired object and calling a method from that object

我有一个 class 如下所示:

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);
    }
}

我的测试class如下图:

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);
    }

但是when(obj.getPoint)不起作用,实际调用中的参数是nullclassService。这行

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

正在获取 null 个参数。

您似乎在 Service class 中使用 Spring 而在单元测试中没有使用 Spring。当你现在模拟 class ServiceTest 中的所有成员变量时,单元测试并没有真正测试 Service class 中的任何内容。 一种解决方案是在单元测试中手动设置 service 实例。

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);
    }

但对我来说还不清楚你真正想测试什么。