Я пытаюсь придумать несколько тестов на интеграцию для службы загрузки Spring.Поскольку сервис использует AWS SQS и DynamoDB, я склонен использовать модуль тестовых контейнеров Localstack для встроенных тестов.Но хотя я думаю, что я включил весь необходимый код, LocalStackContainer, похоже, не запускается, и выдается следующая ошибка:
com.amazonaws.SdkClientException: Unable to execute HTTP request: Connect to localhost:4576
[localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused (Connection refused)
Кстати, если я использую автономный локальный стек (т. Е. Запускаю вручную в терминале'$ localstack start'), интеграционные тесты пройдут.
Может кто-нибудь помочь мне выяснить, чего мне не хватает?
В build.gradle у меня есть
testCompile("org.testcontainers:testcontainers:1.10.6")
testCompile("org.testcontainers:localstack:1.10.6")
В суперклассе я настраиваю некоторый общий контекст тестирования, такой как этот, включая LocalStackContainer как @ ClassRule
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("local")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class)
@Slf4j
public class BaseIntegrationTest extends CamelTestSupport {
@Value("${isLocal:false}")
protected boolean isLocal;
@Value("${isLocalStack:true}")
protected boolean isLocalStack;
@Value("${instanceUrl}")
protected String instanceUrl;
@LocalServerPort
private int serverPort;
@EndpointInject(uri = "mock:endPoint")
protected MockEndpoint mockEndpoint;
protected ApplicationContext appContext;
protected AmazonDynamoDB amazonDynamoDB;
protected AmazonSQS amazonSQS;
protected CamelContext camelContext;
protected Exchange exchange;
protected ProducerTemplate producerTemplate;
@ClassRule
public static LocalStackContainer localstack = new LocalStackContainer()
.withEnv("HOSTNAME_EXTERNAL", DockerClientFactory.instance().dockerHostIpAddress())
.withExposedPorts(4569, 4576) // mock DynamoDB (http port 4569), mock SQS (http port 4576)
.withStartupAttempts(3)
.withStartupTimeout(Duration.ofMinutes(3))
.withServices(DYNAMODB, SQS);
@BeforeClass
public static void init() {
localstack.start();
}
@AfterClass
public static void teardown() {
localstack.stop();
}
@Before
public void setup() throws Exception {
RestAssured.enableLoggingOfRequestAndResponseIfValidationFails();
RestAssured.port = serverPort;
if (instanceUrl != null) {
RestAssured.baseURI = instanceUrl;
} else {
RestAssured.requestSpecification = new RequestSpecBuilder()
.setBaseUri(System.getProperty("APP_HOST", "http://localhost:" + serverPort))
.build();
}
String dynamoDBEndpoint = "http://" + localstack.getContainerIpAddress()
+ ":" + localstack.getMappedPort(4569);
String sqsEndpoint = "http://" + localstack.getContainerIpAddress()
+ ":" + localstack.getMappedPort(4576);
log.info("The integration test is using localstack dynamoDBEndpoint={} and sqsEndpoint={}",
dynamoDBEndpoint, sqsEndpoint);
appContext = new SpringApplicationBuilder(Application.class)
.profiles("local")
.properties("localstackDynamoDBEndpoint=" + dynamoDBEndpoint,
"localstackSQSEndpoint=" + sqsEndpoint)
.run();
amazonDynamoDB = appContext.getBean(AmazonDynamoDB.class);
amazonSQS = appContext.getBean(AmazonSQS.class);
camelContext = appContext.getBean(CamelContext.class);
producerTemplate = camelContext.createProducerTemplate();
}
@After
public void cleanup() {
((ConfigurableApplicationContext) appContext).close();
}
}
В тестовом классе, расширяющем суперкласс, это просто некоторый перестрахованный код, подобный этому
@Test
public void test400Response() {
given()
.body("")
.contentType("application/json")
.post("/root/my_service/v1")
.then()
.statusCode(HttpStatus.SC_BAD_REQUEST)
.body("message", Matchers.equalTo("Missing expected content"))
.log()
.all();
}
А если вы хотите посмотреть, вот журнал успешных тестов
https://justpaste.it/success-with-running-localstack
и журнал неудачных тестов
https://justpaste.it/failed-with-localstackContainer