JUnit通过 restTemplate模拟外部休息调用。

问题描述 投票:0回答:1

我正试图写一个集成测试,其中我在模拟使用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调用控制器,从那里进入上面的服务,其中有休息调用,但不能模拟实际调用。谁能指导我一下?

java spring junit4 spring-junit
1个回答
0
投票

你没有将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);
© www.soinside.com 2019 - 2024. All rights reserved.