我这边在做单元测试覆盖率的测试,因为有个工具类中的一个方法不能通过具体的实际数据返回,所以需要模拟,当前项目用的是PowerMockito,我这边在模拟的时候报了空指针异常,debug发现,程序在执行PowerMockito.when这个语句时,进入了方法内部逻辑,没有模拟返回,请问一下我这个要怎么模拟才可以啊,代码如下:
工具类
@Component
@Slf4j
public class routerutil {
public static final string piccycpt = "picc-ycpt";
public static final string URL_GETCOMCODE ="/common/getCwComCode";
public static final string cW_coM_code ="cwComCode";
@Autowired
private RestTemplateUtil restTemplate:
public ApiResponse doPostForobj(string value, string url) {
JSONObject param = new JSONObject();
param.put("comCode",value);
return restTemplate.postForobj(param, url, ApiResponse.class);
测试类:
@RunWith(PowerMockRunner.class)
public class RouterutilTest {
private RouterUtil routerUtil = new RouterUtilo;
private RestTemplateUtil restTemplate = new RestTemplateUtil();
private ApiResponse apiResponse = new ApiResponse();
@Before
public void setup() {
Whitebox.setInternalstate(routerUtil, fieldName: "restTemplate",restTemplate);
@Test
public void dopostForObjTest() {
try {
Map<String,String> testMap = new HashMap<>();
testMap.put("test","test");
apiResponse.setData(testMap);
//Mockito.when(restTemplate.postFor0bj(Mockito.any(JSONObject.class)Mockito.anyString(),ApiResponse.class)).thenReturn(apiResponse
//Class<?>[] paramTypes =new Class[]{Object.class,string.class, Class.class};
//PowerMockito.stub(PowerMockito.method(RestTemplateUtil.class,“postFor0bj",paramTypes)).toReturn(apiResponse);
PowerMockito.when(restTemplate.postFor0bj(RestTemplateUtil.class,url: "postFor0bj",Mockito.anyO)).thenReturn(apiResponse);
Apiresponse result = routerUtil.doPostForObj( value: "test", url: "test");
}catch (Exception e){
e.printstackTrace();
}}
工具类中引入的RestTemplateUtil类:
报错语句如截图:
因为在模拟返回的时候,进入了RestTemplateUtil源码逻辑,而创建RestTemplateUtil对象时,没有深层次创建,所以这里报了空指针异常。当我给RestTemplateUtil中的restTemplate初始化值以后,又会报其他的错。我觉得模拟的时候应该不关心这个方法内部的逻辑,只要是调用到这个方法就应该返回模拟的结果,不清楚为什么进入了方法内部。
博主2301测试:
博主夜枭龙测试:
博主蓝白测试:
你好,根据你提供的代码,可以尝试以下两种方法来模拟 restTemplate.postForobj 方法的返回值:
1 使用 Mockito 来进行模拟
在测试方法中,可以使用 Mockito 的 Mockito.when() 方法来模拟 restTemplate.postForobj 方法的返回值,示例代码如下:
Mockito.when(restTemplate.postForobj(Mockito.any(JSONObject.class), Mockito.anyString(), Mockito.eq(ApiResponse.class)))
.thenReturn(apiResponse);
2 使用 PowerMockito 来进行模拟
在测试方法中,可以使用 PowerMockito 的 PowerMockito.when() 方法来模拟 restTemplate.postForobj 方法的返回值,示例代码如下:
PowerMockito.when(restTemplate.postForobj(Mockito.any(JSONObject.class), Mockito.anyString(), Mockito.eq(ApiResponse.class)))
.thenReturn(apiResponse);
其中,Mockito.any() 方法表示任意类型的参数都可以匹配,Mockito.eq() 方法表示匹配指定的参数值。
请注意,在使用 PowerMockito 进行单元测试时,需要在测试类的头部使用 @RunWith(PowerMockRunner.class) 注解来运行测试类。
@RunWith(PowerMockRunner.class)
public class RouterUtilTest {
// 测试代码
}
希望能帮到你!
引用chatGPT作答,根据你提供的代码,有几个问题需要解决:
1.工具类中的 RestTemplateUtil 应该是使用 @Autowired 注解注入的,但是在测试类中直接 new 了一个,这会导致工具类使用的不是测试类中的 RestTemplateUtil 实例,而是一个新的实例。解决方法是将测试类中的 RestTemplateUtil 实例注入到工具类中,可以使用 PowerMockito 的 @InjectMocks 注解实现。
2.在模拟 restTemplate.postForobj 方法时,使用了错误的方法名称 postFor0bj,应该改为 postForobj。此外,模拟方法的第三个参数应该是 Class.class,而不是 ApiResponse.class。正确的模拟语句应该是:
PowerMockito.when(restTemplate.postForobj(Mockito.any(JSONObject.class), Mockito.anyString(), Mockito.any(Class.class)))
.thenReturn(apiResponse);
3.在模拟 restTemplate.postForobj 方法时,第一个参数使用了 Mockito.any(JSONObject.class),这会导致实际调用时的参数无法匹配。正确的方法是使用 Mockito.anyString(),因为实际调用时传入的是字符串类型的参数。正确的模拟语句应该是:
PowerMockito.when(restTemplate.postForobj(Mockito.anyString(), Mockito.anyString(), Mockito.any(Class.class)))
.thenReturn(apiResponse);
综上所述,你可以尝试修改测试类中的代码如下:
@RunWith(PowerMockRunner.class)
public class RouterutilTest {
@InjectMocks
private RouterUtil routerUtil;
@Mock
private RestTemplateUtil restTemplate;
private ApiResponse apiResponse = new ApiResponse();
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void dopostForObjTest() {
try {
Map<String,String> testMap = new HashMap<>();
testMap.put("test","test");
apiResponse.setData(testMap);
PowerMockito.when(restTemplate.postForobj(Mockito.anyString(), Mockito.anyString(), Mockito.any(Class.class)))
.thenReturn(apiResponse);
Apiresponse result = routerUtil.doPostForObj(value: "test", url: "test");
} catch (Exception e) {
e.printstackTrace();
}
}
}
希望能够帮助到你!
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
从代码逻辑上来看,您的测试用例的代码是正确的,应该可以成功模拟接口返回数据。但是根据您提供的截图,我看到了一些可疑的地方。主要有以下几点:
RestTemplateUtil
是一个自己定义的类,而不是 RestTemplate
的一个子类。在模拟返回数据时,您使用了 PowerMockito.when(restTemplate.postFor0bj(RestTemplateUtil.class,url: "postFor0bj",Mockito.anyO)).thenReturn(apiResponse)
,但是这里的 RestTemplateUtil.class
参数是不正确的,应该改为 restTemplate.getClass()
。
此外,您在测试用例中也没有正确构造 mock 数据,因为 restTemplate.postForobj(param, url, ApiResponse.class)
方法的第一个参数是一个 JSONObject
类型,且打印堆栈的日志中也发现了一个 JSONObject
类型的变量。所以正确的写法是 PowerMockito.when(restTemplate.postFor0bj(Mockito.any(JSONObject.class),Mockito.anyString(),Mockito.any(Class.class))).thenReturn(apiResponse)
,并且在测试用例中构造参数应该改为 Mockito.any(JSONObject.class), Mockito.anyString(), Mockito.eq(ApiResponse.class)
。
修改后的完整代码如下:
工具类:
@Component
@Slf4j
public class RouterUtil {
public static final String PICCYCPT = "picc-ycpt";
public static final String URL_GETCOMCODE = "/common/getCwComCode";
public static final String CW_COM_CODE ="cwComCode";
@Autowired
private RestTemplateUtil restTemplate;
public ApiResponse doPostForObj(String value, String url) {
JSONObject param = new JSONObject();
param.put("comCode", value);
return restTemplate.postForObj(param, url, ApiResponse.class);
}
}
测试类:
@RunWith(PowerMockRunner.class)
@PrepareForTest({RouterUtil.class})
public class RouterUtilTest {
private RouterUtil routerUtil = new RouterUtil();
private RestTemplateUtil restTemplate = PowerMockito.mock(RestTemplateUtil.class);
private ApiResponse apiResponse = new ApiResponse();
@Before
public void setup() {
Whitebox.setInternalState(routerUtil, "restTemplate", restTemplate);
}
@Test
public void doPostForObjTest() {
try {
Map<String,String> testMap = new HashMap<>();
testMap.put("test", "test");
apiResponse.setData(testMap);
PowerMockito.when(restTemplate.postForObj(Mockito.any(JSONObject.class), Mockito.anyString(), Mockito.eq(ApiResponse.class))).thenReturn(apiResponse);
ApiResponse result = routerUtil.doPostForObj( value: "test", url: "test");
Assert.assertEquals(apiResponse, result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
希望我的解答可以帮到您解决问题。
如果我的回答解决了您的问题,请采纳!
很抱歉,由于技术能力限制,我无法看到您提供的代码和截图,因此也无法为您提供具体的解决方案。建议您检查以下几点:
如果以上方法均未解决问题,建议您将具体的错误信息和相关代码提供给更具技术能力的IT专家寻求帮助。