Spring Boot-将POST REST请求模拟到外部API

时间:2019-06-24 13:47:52

标签: java rest spring-boot junit mocking

我有一个Spring-Boot 1.5.21应用程序,它用作Angular UI和提供数据的外部API之间的REST网关(长话说–充当UI和数据源之间的身份验证)。请求进入Spring-Boot应用程序,它使用请求有效负载调用数据源API。

我是Spring-Boot单元测试的新手,正在尝试在创建新记录(创建)的Gateway应用程序中编写POST REST方法的测试。我已经阅读了一些教程和其他网站,详细介绍了如何对Spring-Boot API进行单元测试,但没有任何方法可以帮助我解决这种情况。

我要:

  • 对REST Controller方法进行单元测试,并检查@RequestBody是否有效
  • 我不希望在数据源中创建记录

控制器方法:

@PostMapping(value = "/" + Constants.API_CHANGE_REQUEST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public String submitChangeRequest(@RequestBody ChangeRequestWrapper changeRequestWrapper) {
    logger.info("API Request: Posting Change Request: " + changeRequestWrapper.toString());
    return restService.makeApiPost(sharedDataService.buildApiUrlPath(Constants.API_CHANGE_REQUEST), changeRequestWrapper);
}

AppConfig:

@PropertySource({"classpath:application.properties"})
@Configuration
public class AppConfig {

    @Resource
    private Environment env;

    @Bean
    public RestTemplate restTemplate() {
        RestTemplateBuilder builder = new RestTemplateBuilder();
        return builder
                .setConnectTimeout(Constants.API_TIMEOUT_CONNECT)
                .setReadTimeout(Constants.API_TIMEOUT_READ)
                .basicAuthorization(env.getProperty("bpm.user"), env.getProperty("bpm.password"))
                .build();
    }
}

RestServiceImpl:

@Service
public class RestServiceImpl implements RestService {

    private static final Logger logger = LoggerFactory.getLogger(RestServiceImpl.class);

    @Autowired
    private RestTemplate myRestTemplate;

    @Value("${bpm.url}")
    private String restUrl;

    public String getApiUri() {
        return restUrl;
    }

    public String makeApiCall(String payload) /*throws GradeAdminException */{
        logger.info("Implementing API call.");
        logger.debug("userApi: " + payload);
        return myRestTemplate.getForObject(payload, String.class);
    }

    public String makeApiPost(String endpoint, Object object) {
        logger.info("Implementing API post submission");
        logger.debug("userApi endpoint: " + endpoint);
        return myRestTemplate.postForObject(endpoint, object, String.class);
    }
}

SharedDataServiceImpl:

@Service
public class SharedDataServiceImpl implements SharedDataService {

    @Autowired
    private RestService restService;

    @Override
    public String buildApiUrlPath(String request) {
        return buildApiUrlPath(request, null);
    }

    @Override
    public String buildApiUrlPath(String request, Object parameter) {
        String path;
        UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(restService.getApiUri());

        if (parameter != null) {
            builder = builder.path(getApiPath(request) + "/{object}");
            UriComponents buildPath = builder.buildAndExpand(parameter);
            path = buildPath.toUriString();
        } else {
            builder = builder.path(getApiPath(request));
            path = builder.build().toUriString();
        }

        return path;
    }
}

我对GET方法所做的事情:

@RunWith(SpringRunner.class)
@WebMvcTest(ClientDataRequestController.class)
@ContextConfiguration(classes = { TestConfig.class }, loader = AnnotationConfigWebContextLoader.class)
public class ClientDataRequestControllerTest {

    @Autowired
    private MockMvc mvc;

    @Before
    public void setUp() {

    }

    @Test
    public void test_no_endpoint() throws Exception {
        this.mvc.perform(get("/")).andExpect(status().isNotFound()).andReturn();
    }

    @Test
    public void test_controller_no_endpoint() throws Exception {
        this.mvc.perform(get("/api/")).andExpect(status().isOk()).andReturn();
    }

    @Test
    public void test_getStudent_valid_parameters() throws Exception {
        this.mvc.perform(get("/api/students/?pidm=272746")).andExpect(status().isOk()).andReturn();
    }
}

对此我将不胜感激。

解决方案:

此后,我发现this SO answer可以解决我的问题。

1 个答案:

答案 0 :(得分:0)

您可以模拟RestServiceImpl。在测试中添加一个依赖项,并使用MockBean对其进行批注:

@MockBean
private RemoteService remoteService;

现在您可以继续模拟方法了:

given(this.remoteService.makeApiPost()).willReturn("whatever is needed for your test");