citrusframework / citrusframework/citrus

Mock Parallel Third Party Server Communication

Open
#1,350 3 comments 0 reactions 0 assignees View on GitHub
question
Dominant language
Java
Stars
485
Forks
155
Avg merge
4d 22h
Merged PRs (30d)
6

Description

**Citrus Version**
4.5.2 ( can be reproduced with 4.6 as well)

**Question**
How can I mock parallel server communication with third party system?

Use Case:
Citrus client calls SUT which calls third party system. Now I want to do the same but in parallel. Two parallel client requests are sufficient. For client requests I know I need to use a selector in the response (example from docs works great without mocking the server communication using citrus_message_id), but how can I do the same for server request and response mocking?

**What I've tried so far**
1. Use parallel container with sequential block (closest to what I could find in the docs and what I actually like to do)
```java
runner.run(parallel()
.actions(
sequential().actions(
createForkedRequest(httpClient, "ClientA"),
mockThirdPartyServerRequest(),mockThirdPartyServerResponse(),
createResponse(httpClient, "ClientA")),
sequential().actions(
createForkedRequest(httpClient, "ClientB"),
mockThirdPartyServerRequest(),mockThirdPartyServerResponse(),
createResponse(httpClient, "ClientB"))
));
```
This will run into "Failed to find reply channel for message correlation key: citrus_message_id = 'ffce4ac3-4f4e-47a4-a755-541deea1cff0'" error.
2. Use parallel container only for client request and response mocking (separate parallel containers), while server communication is mocked in a sequential container in between (this works, but doesn't cover my goal)
```java
runner.run(parallel()
.actions(
createForkedRequest(httpClient, "ClientA"),
createForkedRequest(httpClient, "ClientB")
));

runner.run(sequential().actions(mockThirdPartyServerRequest(),mockThirdPartyServerResponse(),
mockThirdPartyServerRequest(),mockThirdPartyServerResponse()));

runner.run(parallel()
.actions(
createResponse(httpClient, "ClientA"),
createResponse(httpClient, "ClientB")
));
```
3. Use 3 parallel container one for client request one for server communication one for client response (just to be on the save side, that client and s)
```java
runner.run(parallel()
.actions(
createForkedRequest(httpClient, "ClientA"),
createForkedRequest(httpClient, "ClientB")
));

runner.run(parallel().actions(mockThirdPartyServerRequest(),mockThirdPartyServerResponse(),
mockThirdPartyServerRequest(),mockThirdPartyServerResponse()));

runner.run(parallel()
.actions(
createResponse(httpClient, "ClientA"),
createResponse(httpClient, "ClientB")
));
```
**Additional information**
My overarching goal is to manipulate the third party requests and test how my SUT behaves under different scenarios, so running the 3rd party requests in sequential order is not an option.
e.g: SUT creates an entity in DB and locks it when a specific endpoint is called. While SUT holds the lock it will do some 3rd party communication which I need to delay so that the second request can run into the lock error reliable.

I added an [Example Project](https://github.com/user-attachments/files/20458658/ServerWithITTest.zip) containing a server which does a simple request on the only endpoint and junit test suite to demonstrate what I tried.

Contributor guide

Open the contributing guide

Research direction

Start with the attached Example Project and reproduce the correlation error from the parallel()/sequential() runner setup on Citrus 4.5.2 or 4.6. Read the parallel container and server request/response mocking entry points to determine how concurrent third-party exchanges can be correlated; done should provide a supported approach or clearly documented limitation for this scenario.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.