Spring in Practice: JMS Testing


JMS Listener Erstellen

Wir erstellen erstmals eine Klasse für JMS um Entitäten zu lesen. Hier zu sehen ist durch @Component kann Spring es Intializieren und wegen @ConditionalOnProperty wird es nur denn intializiert wenn property auf  TEST_JMS_PUBLISH_BOOK vorhanden ist. Dadurch wenn eine Topic wird von uns geschreiben wir bekommen es mit.

Mit @JmsListener können wir auf bestimmte Topic lesen und geben an welche container Factory um eine Message Listener Container zu erstellen.

Der soll denn SyncMessage von JMS Topic lesen. Diese soll denn uns die daten zurückliefern können.

@Component
@ConditionalOnProperty(TEST_JMS_PUBLISH_BOOK) // set Property when it should be intialized by spring
Public class TestBookJmsListener {
    privateList < BookMessageDTO > receivedBooks = Collections.synchronizedList(newArrayList < > ());
    //ADD JMS LISTENER AND GET TOPIC
    @JmsListener(
        destination = BOOK_TOPIC,
        containerFactory = TestJmsConfiguration.BOOK_LISTENER_CONTAINER_FACTORY_NAME)
    @Transactional
    Public void receiveBookMessage(BookMessageDTOmessage, @Header("revision") int revId) {
        this.receivedBooks.add(message);
    }
    publicList < BookMessageDTO > getReceivedBooks() {
        Return this.receivedBooks;
    }
    Public void clear() {
        this.receivedBooks.clear();
    }
    Public String toString() {
        returnthis.receivedBookts.toString();
    }
}

Test Erstellen

Hier legen wir mit @TestPropertySource fest dass es soll mit ausprägung ausgeführt werden  JMS SYNC enabled  und TEST_JMS_PUBLICH_BOOKS.

@DirtiesContext sagt Spring soll nach der Test Kontext wieder erstellen als durch test malformed ist.

In der Test erstellen wir eine DTO um entität zu speichern und  speichern es mit Service. Warum nehmen wir Service hier und nicht Repository? Das sagte ich in andere Blog.

Nach der speicher wir warten bis JMS Listener was zuruckgibt und denn Assertions gemacht. Hier sehen wir eine methode um 10 sekunden zu warten solange bis jms listener nicht leer ist.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = AiApp.class)
@WebAppConfiguration
@TestPropertySource(properties = {
    Constants.PROP_SYNC_ENABLED + "=true",
    TEST_JMS_PUBLISH_BOOKS + "=true"
}) // Property  intialized by spring so that above test jms works
@DirtiesContext
@Autowired
privateBookService bookService;

@Autowired
privateTestBookJmsListener bookJmsListener;

Long nbookId;

@Test
Public void testBookPublishing() throwsException {
    BookDTO bookDTO = newBookDTO(); //Intialize Test DTO data to save entity
    bookDTO.setName(NAME);
    ..
    bookDTO = bookService.save(bookDTO); //save entity  and wait for jms data and make assertions
    bookId = bookDTO.getId();
    waitForBookReceived();
    assertThat(bookJmsListener.getReceivedBooks()).hasSize(1);
    ..

    bookJmsListener.clear();

    this.bookService.delete(bookId);

    waitForBookReceived(); //delete entity  and wait for jms data and make assertions

    assertThat(bookJmsListener.getReceivedBooks()).hasSize(1);

}

protectedvoidwaitForBookReceived() //waiting for jms data
{
    await ().atMost(10, TimeUnit.SECONDS)
        .pollDelay(100, TimeUnit.MILLISECONDS)
        .until(() - > !bookJmsListener.getReceivedBooks().isEmpty());

    if (bookJmsListener.getReceivedBooks().isEmpty()) {
        fail("NoBookreceived");
    }
}
}