我有一个服务类,出于可读性考虑,我为代码提供了虚拟变量和对象。我试图主要使用Mockito编写该服务的JUNIT测试类。无论我多么努力,无论使用间谍/模拟,我都无法使用serviceMethod方法。在主要课程之后,我还包括了我编写的测试。
测试通过,没有任何错误,但是无法从实际的类中调用该方法。此后,它不再包含在测试范围内。 (实际类中的方法在Eclipse / SONAR报告中以红色排除)
我知道我在这里遗漏了一些东西,但是并没有想到。我需要检查一下,让我知道如何为此编写适当的测试类并获得该方法的覆盖范围。
(P.S。所有必要的导入均已就位,为了简洁起见,此处未粘贴)
谢谢!
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class ServiceClass {
private static final Logger LOGGER = LoggerFactory.getLogger(ServiceClass.class);
@Autowired
private Config Config;
@Autowired
private RestTemplate restTemplate;
public void serviceMethod(BusinessClass businessObject) {
String NotificationUrl = Config.getApplicationProperty(businessObject.getCode()).getNotificationUrl();
HttpEntity<StoreNotify> request = new HttpEntity<>(businessObject);
ResponseEntity<String> response = restTemplate.exchange(NotificationUrl, HttpMethod.POST, request,
String.class);
LOGGER.info("Service call, response: {} and status: {} ", response.getBody(),
response.getStatusCode());
}
}
上述测试类,
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
@RunWith(MockitoJUnitRunner.Silent.class)
public class ServiceClassTest {
@InjectMocks
private ServiceClass serviceClass;
@Mock
private RestTemplate restTemplate;
@InjectMocks
private BusinessClass businessObject;
@Test
public void testServiceMethod() {
ServiceClass spy = Mockito.spy(serviceClass);
doNothing().when(spy).serviceMethod(businessObject);
spy.serviceMethod(businessObject);
verify(spy, times(1)).serviceMethod(businessObject);
ResponseEntity<String> responseEntity = new ResponseEntity<>(HttpStatus.ACCEPTED);
Mockito.when(restTemplate.exchange(ArgumentMatchers.anyString(), ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.<HttpEntity<BusinessClass>>any(), ArgumentMatchers.<Class<String>>any()))
.thenReturn(responseEntity);
}
}
答案 0 :(得分:0)
您可以尝试以下代码。如果失败,您可能需要进行一些更改,如果下面的代码不起作用,请仅注释您的结果。
@RunWith(MockitoJUnitRunner.Silent.class)
public class ServiceClassTest {
@InjectMocks
private ServiceClass serviceClass;
@Mock
private RestTemplate restTemplate;
@Mock
private Config Config;
@Test
public void testServiceMethod() {
BusinessClass businessObject = new BusinessClass();
businessObject.setCode("123"); // set as per your datatype
ResponseEntity<String> responseEntity = new ResponseEntity<>("my String mock body", HttpStatus.ACCEPTED);
Mockito.when(restTemplate.exchange(Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any()))
.thenReturn(responseEntity);
serviceClass.serviceMethod(businessObject);
verify(serviceClass, times(1)).serviceMethod(Mockito.any(BusinessClass.class));
}
}
答案 1 :(得分:0)
为了简单起见,我将添加以下测试类,它确实足以满足您的情况。
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.RestTemplate;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class ServiceClassTest {
private static final String CODE = "code";
private static final String NOTIFICATION_URL = "notificationUrl";
@Mock
private Config config;
@Mock
private RestTemplate restTemplate;
@InjectMocks
private ServiceClass serviceClass;
@Mock
private BusinessClass businessObject;
@Mock
private Notification notification;
@Test
public void serviceMethod() {
when(businessObject.getCode()).thenReturn(CODE);
when(config.getApplicationProperty(CODE)).thenReturn(notification);
when(notification.getNotificationUrl()).thenReturn(NOTIFICATION_URL);
serviceClass.serviceMethod(businessObject);
verify(restTemplate, times(1)).exchange(NOTIFICATION_URL, HttpMethod.POST, new HttpEntity<>(businessObject), String.class);
}
}
如果我要简要说明此测试方法的作用
ServiceClass
中的代码。因此,在第1行中:我确保businessObject.getCode()
返回我想要的CODE
。请注意,businessObject
是我们要传递到测试方法内的ServiceClass.serviceMethod(BusinessClass businessObject)
的参数。现在我知道,无论是哪种情况,businessObject.getCode()
都会返回CODE
,这样,当我调用ServiceClass.serviceMethod
时,在我的Config.getApplicationProperty(String code)
(原始类)中,CODE
将通过作为参数。现在在第2行中:我建议每当将CODE
作为config.getApplicationProperty(String code)
的参数传递时,返回我想要的notification
。在第3行中:我建议notification.getNotificationUrl()
依次返回NOTIFICATION_URL
。Mockito.verify
来确保执行是按照我的模拟安排和实际(原始)类逻辑内联进行的。在这里,我要验证的是执行的代码称为restTemplate
的方式。 正如我在一开始提到的,我上面写的是一个简单的测试,可以满足您的要求。消化完这些之后,您可以看看mock-server,这可能对您进行测试休息电话很有帮助。