Testing Java Event Handlers
Integration testing
For the latest information on testing, go to our page on Integration testing.
The Genesis Platform provides the AbstractGenesisTestSupport
abstract class that enables end-to-end testing of specific areas of your application.
In this case, build GenesisTestConfig
with the following information:
- Set packages:
global.genesis.eventhandler
this is the standard package name from the framework, which is needed for all Java events/custom events. Make sure you name the package where you defined the events. In the example below, it isglobal.genesis.position.samples.events.rxjava
- Set genesis home
- Set initial data: we want to ensure that we have a database, seeded with information
public class TradingEventHandlerTest extends AbstractGenesisTestSupport<EventResponse> {
public TradingEventHandlerTest() {
super(GenesisTestConfig.builder()
.setPackageNames(List.of("global.genesis.eventhandler","global.genesis.position.samples.events.rxjava"))
.setGenesisHome("/GenesisHome/")
.setInitialDataFiles("seed-data.csv")
.setParser(EventResponse.Companion)
.build()
);
}
}
For more information about AbstractGenesisTestSupport
, see the Testing pages.
Once you have set up your configuration, you can start writing tests against your Event Handler.
Writing tests
Let's write some tests for the simple Event Handler defined below:
@Module
public class EventTrade implements Rx3ValidatingEventHandler<Trade, EventReply> {
private final RxEntityDb entityDb;
@Inject
public EventTrade(RxEntityDb entityDb) {
this.entityDb = entityDb;
}
@Nullable
@Override
public String messageType() {
return "TRADE_INSERT";
}
@NotNull
@Override
public Single<EventReply> onCommit(@NotNull Event<Trade> tradeEvent) {
Trade trade = tradeEvent.getDetails();
return entityDb.writeTransaction(txn -> {
Trade result = txn.insert(trade).blockingGet().getRecord();
return ack(this, List.of(Map.of("TRADE_ID", result.getTradeId())));
}).map(result -> result.getFirst());
}
@NotNull
@Override
public Single<EventReply> onValidate(@NotNull Event<Trade> event) {
Trade trade = event.getDetails();
if (entityDb.get(Counterparty.byId(trade.getCounterpartyId())).blockingGet() == null) {
return Single.just(new StandardError("INTERNAL_ERROR", "COUNTERPARTY ById(counterpartyId=" + trade.getCounterpartyId() +") not found in database").toEventNackError());
} else if (entityDb.get(Instrument.byId(trade.getInstrumentId())).blockingGet() == null) {
return Single.just(new StandardError("INTERNAL_ERROR", "INSTRUMENT ById(instrumentId=" + trade.getInstrumentId() +") not found in database").toEventNackError());
}
return ack(this);
}
}
Simple test
Below is an example of a simple test.
First, this creates an Event
object, setting the event details and specifying the intended Event Handler for the message "EVENT_TRADE_INSERT" and username.
Second, it sends a message to the Event Handler using getMessageClient().request(event, EventReply.class)
. The result is first verified to be an EventAck
.
Finally, it checks that the inserted trade can be retrieved from the database.:
@Test
public void testTradeInsert() throws InterruptedException {
Trade trade = Trade.builder()
.setTradeId("1")
.setCounterpartyId("CP1")
.setInstrumentId("I2")
.setSide("BUY")
.setPrice(1.123)
.setQuantity(1000)
.build();
Event event = new Event(trade, "EVENT_TRADE_INSERT", "JohnDoe");
EventReply reply = getMessageClient().request(event, EventReply.class).blockingGet();
assertEquals(reply, new EventReply.EventAck(List.of(Map.of("TRADE_ID", trade.getTradeId()))));
Trade result = getRxDb().entityDb().get(Trade.byId("1")).blockingGet();
assertNotNull(result);
}
Error response test
You may also want to test a negative case, where you expect to receive an error as a response.
In the example below, we expect the response to be of type EventNack
when we try to insert a wrong instrument ID. As in the Event Handler above, there is a check to see if the instrument exists in the database.
@Test
public void testTradeInsertWrongInstrumentId() throws InterruptedException {
Trade trade = Trade.builder()
.setTradeId("1")
.setCounterpartyId("CP1")
.setInstrumentId("DOESNOTEXIST")
.setSide("BUY")
.setPrice(1.213)
.setQuantity(100)
.build();
Event event = new Event(trade, "EVENT_TRADE_INSERT_JAVA", "JohnDoe");
EventReply reply = getMessageClient().request(event, EventReply.class).blockingGet();
GenesisError genesisError = new StandardError("INTERNAL_ERROR", "INSTRUMENT ById(instrumentId=DOESNOTEXIST) not found in database");
assertEquals(reply, new EventReply.EventNack(List.of(), List.of(genesisError)));
}