Thursday, October 31, 2013

Testing QuickFix/J messages

Some short time ago we've been using QuickFix/J for sending and receiving messages. The library was ok, but to write tests for it was kind of painfull. For example our verification of created messages looked like this:
assertThat(message, instanceOf(AllocationInstruction.class));
assertThat(message.getHeader().getString(SenderSubID.FIELD), is("senderSubId-123"));
assertThat(message.getString(AllocID.FIELD), is("allocId-123"));
assertThat(message.getInt(AllocType.FIELD), is(AllocType.CALCULATED));
assertThat(message.getChar(AllocTransType.FIELD), is(AllocTransType.NEW));
assertThat(message.getDecimal(Shares.FIELD), is(new BigDecimal("1000000")));

assertThat(message.getInt(NoAllocs.FIELD), is(2));

AllocationInstruction.NoAllocs allocationGroup;
allocationGroup = (AllocationInstruction.NoAllocs) message.getGroup(1, new AllocationInstruction.NoAllocs());
assertThat(allocationGroup.getString(IndividualAllocID.FIELD), is("1"));
assertThat(allocationGroup.getString(AllocAccount.FIELD), is("acc-01"));
assertThat(allocationGroup.getDecimal(AllocShares.FIELD), is(new BigDecimal("250000")));

allocationGroup = (AllocationInstruction.NoAllocs) message.getGroup(2, new AllocationInstruction.NoAllocs());
assertThat(allocationGroup.getString(IndividualAllocID.FIELD), is("2"));
assertThat(allocationGroup.getString(AllocAccount.FIELD), is("acc-02"));
assertThat(allocationGroup.getDecimal(AllocShares.FIELD), is(new BigDecimal("750000")));
The code was not very readable and we also had to catch FieldNotFound exception each time we were doing this. To resolve this inconvenience I've created my own hamcrest matcher that can be used like this:
assertThat(message, isFIXMessage()
        .ofType(AllocationInstruction.class)
        .with(header().with(SenderSubID.FIELD, "senderSubId-123"))
        .with(AllocID.FIELD, "allocId-123")
        .with(AllocType.FIELD, AllocType.CALCULATED)
        .with(AllocTransType.FIELD, AllocTransType.NEW)
        .with(Shares.FIELD, "1000000")
        .with(NoAllocs.FIELD, 2)
        .with(group(1, NoAllocs.FIELD)
                .with(IndividualAllocID.FIELD, 1)
                .with(AllocAccount.FIELD, "acc-01")
                .with(AllocShares.FIELD, new BigDecimal("250000"))
        )
        .with(group(2, NoAllocs.FIELD)
                .with(IndividualAllocID.FIELD, 2)
                .with(AllocAccount.FIELD, "acc-02")
                .with(AllocShares.FIELD, new BigDecimal("750000"))
        )
);
The source code can be found/is stored under my project: QuickFixUtils.