java - 通过restTemplate进行JUnit模拟外部休息调用

标签 java spring junit4 spring-junit

我正在尝试编写一个集成测试,其中在模拟使用 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 调用 Controller ,并从那里进入上面的服务,该服务有休息调用,但无法模拟实际的调用。 有人可以指导我吗?

最佳答案

您没有将 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);

关于java - 通过restTemplate进行JUnit模拟外部休息调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61650118/

相关文章:

java - Spring 服务层的 JUnit 测试用例

java - 将图像从数据库加载到 Spring 应用程序上下文中。我使用mybatis api

java - Android - 如何在每次打开应用程序时启动完全相同的 Activity ?

java - 如何在 android 适配器中使用 Roboguice 依赖注入(inject)

java - JUnit 测试自定义异常

junit - 如何使用 MockWebServer 验证 POST 正文的内容?

java - 将动画 gif 从 JAR 文件加载到 ImageIcon

java - Spring、AngularJS 和 Maven 之间的联系

java - 切换到 Java 1.8-Spring 4 后无法打开 ServletContext 资源 [/jdbc.properties]

java - 在当前项目和插件组中找不到前缀 'spring' 的插件