我正试图写一个集成测试,其中我在模拟使用JUnit调用外部服务器的rest调用时出现了问题。我已经添加了一个 @Mock 和 @InjectMock 在役
服务是这样的。
@Service
public class BoundaryDeltaService {
private BoundaryDelta getBoundaryDeltaUsingApp() {
List<BoundaryValueInfo> infoFromSource = Arrays.asList(serviceAdapter.readInfoFromApiUsingApp(boundarySet, app, loginUserInfo));
return getBoundaryDeltacompareCurrentBoundaryValuesWithSource(boundarySet, infoFromSource );
}
}
还有另一个服务有 restTemplate 的调用。
@Service
public class ServiceAdapter {
public BoundaryValueInfo[] readInfoFromApiUsingApp(){
String loginToken = systemUserLoginService.getSystemUserTokenManual(app, loginUserInfo);
restTemplate = createRestTemplate(boundarySet);
HttpHeaders headers = new HttpHeaders() {{
String authHeader = "Bearer " + loginToken;
set( "Authorization", authHeader );
}};
HttpEntity<String> request = new HttpEntity<String>(headers);
ResponseEntity<BoundaryValueInfo[]> answerFromApi = restTemplate.exchange(boundarySet.getApiUri(), HttpMethod.GET, request, BoundaryValueInfo[].class);
return getResponseFromApi(answerFromApi);
}
}
这就是测试方案
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles({"aws", "local"})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = FlywayConfig.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
public class BoundaryValueDeltaControllerTest {
private static final String API_V1 = "/api/v1/";
@Autowired
TestRestTemplate testRestTemplate;
@Autowired
private BoundaryDeltaService boundaryDeltaService;
@Autowired
private DomainBuilder domainBuilder;
@Autowired
private AppBuilder appBuilder;
@Autowired
private AppAdminBuilder appAdminBuilder;
@Autowired
private BoundaryValueBuilder boundaryValueBuilder;
@Autowired
private BoundarySetBuilder boundarySetBuilder;
@MockBean
private LoginUserProvider loginUserProvider;
@MockBean
private LoginTokenService loginTokenService;
@InjectMocks
private BoundaryServiceAdapter boundaryServiceAdapter;
@Mock
RestTemplate restTemplate;
@LocalServerPort
private int port;
Domain domain;
App app;
BoundarySet boundarySet;
BoundaryValue boundaryValue;
LoginUserInfo loggedInUser;
@Before
public void setUp() {
clear();
domain = domainBuilder.persist();
app = appBuilder.persist(domain);
boundarySet = boundarySetBuilder.persist(domain);
boundaryValue = boundaryValueBuilder.persist(boundarySet);
}
@After
public void tearDown() {
clear();
}
@BeforeClass
public static void setupTestEnv() {
// https://github.com/localstack/localstack/issues/592
}
@Test
public void updateBoundaryValuesFromApi() {
aLoggedInUser(domain.getAuthor().getUsername());
appAdminBuilder.persist(app, domain.getAuthor());
ResponseEntity<BoundaryValueInfo[]> answerFromApi = getBoundaryValueInfos();
HttpHeaders headers = new HttpHeaders() {{
String authHeader = "Bearer 1234";
set( "Authorization", authHeader );
}};
HttpEntity<String> request = new HttpEntity<>(headers);
//when(restTemplate.exchange(boundarySet.getApiUri(), HttpMethod.GET, request, BoundaryValueInfo[].class)).thenReturn(answerFromApi);
when(restTemplate.exchange(ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(),
ArgumentMatchers.<Class<BoundaryValueInfo[]>>any())
).thenReturn(answerFromApi);
String url = url(API_V1 + "domains/" + domain.getName() + "/boundarysets/" + boundarySet.getBoundarySetName() + "/app/" + app.getName()+ "/updatefromapi/");
ResponseEntity<String> response = testRestTemplate.exchange(url,HttpMethod.GET, null, String.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
}
}
我用api调用控制器,从那里进入上面的服务,其中有休息调用,但不能模拟实际调用。谁能指导我一下?
你没有将TestRestTemplate用于它的目的。
TestRestTemplate并不是RestTemplate的扩展,而是一种替代方案,它简化了集成测试,方便了测试过程中的认证。它有助于Apache HTTP客户端的定制,但也可以作为RestTemplate的封装器使用。
解决办法。
方法1:1) 直接使用RestTemplate对象调用交换方法。
ResponseEntity<String> response = restTemplate .exchange(url,HttpMethod.GET, null, String.class);
2)模拟testRestTemplate,并在对该对象的交换方法调用时进行模拟。
when(testRestTemplate.exchange(ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(),
ArgumentMatchers.<Class<BoundaryValueInfo[]>>any())
).thenReturn(answerFromApi);