3

I want to test a live component which as a result of execution sends a message in a SNS topic.

Is there a way how to create an "inline" client subscription with Java SDK?

Something line this (pseudocode):

@Test
public void testProcessingResult() throws Exception {
    final Box<Object> resultBox = new Box();
    snsClient.subscribe(new SubscribeRequest(topicArn, 
        msg -> resultBox.setValue(extractResult(msg))
    ));
    ...
    httpClient.post(endpoint, params); // send the request
    Thread.sleep(2000); // wait for eventual processing

    assertEquals(expected, resultBox.getValue());
}

One way, how to achieve this, could be to create an Amazon SQS queue and register the test client to it, then to get the result via polling.

Is there an easier way?

ttulka
  • 10,309
  • 7
  • 41
  • 52

1 Answers1

4

As I mentioned in the question, I have created a SQS queue and subscribed it to the SNS topic. Then I can check if the event was published.

private String subscriptionArn;
private String queueUrl;

@BeforeEach
public void createAndRegisterQueue() {
    queueUrl = sqs.createQueue("mytest-" + UUID.randomUUID()).getQueueUrl();
    subscriptionArn = Topics.subscribeQueue(sns, sqs, TOPIC_ARN, queueUrl);
}

@AfterEach
public void deleteAndUnregisterQueue() {
    sns.unsubscribe(subscriptionArn);
    sqs.deleteQueue(queueUrl);
}

@Test
public void testEventPublish() throws Exception {
    // request processing
    Response response = httpClient.execute(new HttpRequest(ENDPOINT));
    assertThat("Response must be successful.", response.statusCode(), is(200));

    // wait for processing to be completed
    Thread.sleep(5000);

    // check results
    Optional<String> published = sqs.receiveMessage(queueUrl).getMessages()
            .stream()
            .map(m -> new JSONObject(m.getBody()))
            .filter(m -> m.getString("TopicArn").equals(TOPIC_ARN))
            .map(m -> new JSONObject(m.getString("Message")))
            // ... filter and map the expected result
            .findAny();

    assertThat("Must be published.", published.isPresent(), is(true));
}

If there is not an easier solution without creating additional resources (queue), this works fine.

ttulka
  • 10,309
  • 7
  • 41
  • 52