【发布时间】:2020-08-22 07:06:50
【问题描述】:
我正在尝试编写一个集成测试,其中在模拟使用 JUnit 调用外部服务器的其余调用时遇到问题。 我在服务中添加了 @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 调用控制器,并从那里进入上述服务,该服务具有休息调用但无法模拟实际调用。 有人可以在这里指导我吗?
【问题讨论】:
-
restTemplateinServiceAdapter不是自动连线的。它是使用createRestTemplate(boundarySet);创建的。如果您的实现是这样的,则不能直接注入模拟。您可以重构您的代码并将createRestTemplate(boundarySet);移动到单独的类并在junit 中模拟该类, -
@Smile 就像,我不能模拟
ServiceAdapter因为它是集成测试,我还必须自动装配 RestTemplate。我的createRestTemplate(boundarySet)什么都不做,但看起来像这样。在完全单独的呼叫中移动它是否相关?private RestTemplate createRestTemplate(BoundarySet boundarySet) { return new RestTemplate(); } -
将
createRestTemplate()移动到像'RestTemplateFactory' 这样的单独类,然后在你的junit 中模拟RestTemplateFactory,而ServiceAdapter将RestTemplateFactory作为@Autowired。 -
@Smile 好的,但问题是当你调用 restTemplate.exchange() 时。我如何设法在 when().thenReurn() 中模拟它?
-
你可以模拟
restTemplateFactory.createRestTemplate()返回模拟的rest模板对象
标签: java spring junit4 spring-junit