Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jupiter-tools/spring-boot-extensions
A lot of JUnit5 Extensions to work with Spring Boot.
https://github.com/jupiter-tools/spring-boot-extensions
Last synced: 2 months ago
JSON representation
A lot of JUnit5 Extensions to work with Spring Boot.
- Host: GitHub
- URL: https://github.com/jupiter-tools/spring-boot-extensions
- Owner: jupiter-tools
- Created: 2019-01-23T05:07:42.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2023-02-25T00:44:56.000Z (almost 2 years ago)
- Last Synced: 2023-07-28T22:19:50.883Z (over 1 year ago)
- Language: Java
- Homepage: http://jupiter-tools.com
- Size: 766 KB
- Stars: 32
- Watchers: 2
- Forks: 6
- Open Issues: 12
-
Metadata Files:
- Readme: README.adoc
Awesome Lists containing this project
README
:toc: preamble
# JUnit5 Spring Boot Extensions
image:https://travis-ci.com/jupiter-tools/spring-boot-extensions.svg?branch=master["Build Status", link="https://travis-ci.com/jupiter-tools/spring-boot-extensions"]
image:https://codecov.io/gh/jupiter-tools/spring-boot-extensions/branch/master/graph/badge.svg[link ="https://codecov.io/gh/jupiter-tools/spring-boot-extensions"]## Database specific tests
image:./images/jpa-containers.png[jpa containers extension scheme]
### TraceSql Extension
Provide you an ability to check SQL statement execution after tests.
You need to add the next dependency:[source,xml]
----com.jupiter-tools
spring-test-jpa
0.2----
And now, you can assert a count of insert operations after save an entity:
[source, java]
----
@ExtendWith(TraceSqlExtension.class)
@ExtendWith(SpringExtension.class)
@SpringBootTest
class TraceSqlExtensionTest {@Autowired
private FooRepository fooRepository;@Test
void testInsert() {
// Act
fooRepository.save(new Foo("any data"));
// Assert
AssertSqlCount.assertInsertCount(1);
}
}
----Also, you can use annotation on the test case to assert the expected count of executed queries:
[source, java]
----
@Test
@ExpectedSqlQuery(type = INSERT, count = 1)
void testInsert() {
fooRepository.save(new Foo("data"));
}@Test
@ExpectedSqlQuery(type = SELECT, count = 1)
void testSelect() {
fooRepository.findAll();
}
----### PostgreSQL Extension
To run the docker postgres image by the test-containers library
in your integration test, you can use PostgresTcExtension.[source,xml]
----com.jupiter-tools
spring-test-postgres
0.2----
Let's try to execute a stored procedure specific to PostgreSQL:
[source, java]
----
@DataJpaTest
@ExtendWith(SpringExtension.class)
@ExtendWith(PostgresTcExtension.class)
@ExtendWith(TraceSqlExtension.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class PostgresTcExtensionTest {@PersistenceContext
private EntityManager entityManager;@Test
@Sql("/stored_functions/test_func.sql")
void testStoredFunc() {
// Arrange
StoredProcedureQuery query = entityManager.createStoredProcedureQuery("rnd");
// Act
query.execute();
// Assert
List resultList = query.getResultList();
int rnd = (int) resultList.get(0);
Assertions.assertThat(rnd).isEqualTo(123);
}
}
----This library provides a wide system of meta-annotations to
simplified writing integration test's configuration.For example, you can write:
[source, java]
----
@EnablePostgresDataTest
class EnablePostgresDataTestTest {
...
}
----instead of:
[source, java]
----
@DataJpaTest
@ExtendWith(SpringExtension.class)
@ExtendWith(PostgresTcExtension.class)
@ExtendWith(TraceSqlExtension.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class PostgresTcExtensionTest {
...
}
----you can see at whole postgres annotation system at the next picture::
image:./images/pg-annotations.png[postgres annotation system]
You can build a necessary test configuration by using annotations which you need. Meta-annotations is a beautiful mechanism which will you a making configuration in a declarative style.
### MySql Extension
MySqlTcExtension runs the mysql docker image and set spring properties
in the configuration to use this datasource in tests.[source,xml]
----com.jupiter-tools
spring-test-mysql
0.2----
You can use this extension by the applying of `EnableMySqlTestContainersExtension` annotation or
you can use `@EnableMySqlDataTest` to write a test with the DataJpa context configuration:[source, java]
----
@EnableMySqlDataTest
class EnableMySqlDataTestTest {@Autowired
private FooRepository repository;@Test
@Commit
@DataSet(cleanBefore = true, cleanAfter = true)
@ExpectedDataSet(value = "/datasets/expected.json", ignoreCols = "ID")
void testCreate() throws Exception {
repository.saveAndFlush(new Foo("any data"));
}
}
----As well as for the PostgreSQL in this library there is a system of meta-annotations for the MySql:
image:./images/mysql-annotations.png[mysql annotation system]
## Messaging systems
image:./images/jms.png[messaging system annotations]
### RabbitMq Extension
`RabbitMqTcExtension` runs the RabbitMq docker image by the TestContainers library
and configure SpringBoot properties to work with this container.[source,xml]
----com.jupiter-tools
spring-test-rabbitmq
0.2----
Now we can run RabbitMq in tests and send a message in a real queue:
[source, java]
----
@SpringBootTest
@ExtendWith(SpringExtension.class)
@ExtendWith(RabbitMqTcExtension.class)
class EnableRabbitMqTestTest {@Autowired
private AmqpTemplate amqpTemplate;@Test
void testSend() {
amqpTemplate.convertAndSend("test-queue", "123");
...}
}
----As well as with database specific tests, in this case, you can use meta-annotation to write tests more pragmatic:
[source, java]
----
@EnableRabbitMqTest
class EnableRabbitMqTestTest {
...
}
----Also, you can assert the sending of messages in the selected queue:
[source, java]
----
@EnableRabbitMqTest
public class ExpectedMessageTest {@Autowired
private AmqpTemplate amqpTemplate;@Test
@ExpectedMessage(queue = "test-queue", message = "123")
void testSend() throws InterruptedException {
amqpTemplate.convertAndSend("test-queue", "123");
}
}
----Also, you can assert the receiving of multiple messages:
[source, java]
----
@Autowired
private AmqpTemplate amqpTemplate;@Test
@ExpectedMessages(queue = "test-queue", <1>
messagesFile = "/datasets/expected_messages.json") <2>
void testSendListOfMessages() {
// first type:
amqpTemplate.convertAndSend("test-queue", new Foo("123"));
// second type:
amqpTemplate.convertAndSend("test-queue", new Bar("AAA",1));
amqpTemplate.convertAndSend("test-queue", new Bar("BBB",2));
amqpTemplate.convertAndSend("test-queue", new Bar("CCC",3));
}
----
<1> queue name
<2> file with expected messages in JSON formatContent of the `expected_messages.json` :
[source,json]
----
{
"com.jupiter.tools.spring.test.rabbitmq.extension.pojo.Foo": [
{
"value":"123"
}
],
"com.jupiter.tools.spring.test.rabbitmq.extension.pojo.Bar":[
{
"name":"AAA",
"count":1
},
{
"name":"BBB",
"count":2
},
{
"name":"CCC",
"count":3
}
]
}
----### ActiveMq Extension
You can run the ActiveMq docker image by the using of `EnableActiveMqTestContainers` annotation.
You need to use the next dependency:
[source,xml]
----com.jupiter-tools
spring-test-activemq
0.2----
image:./images/activemq-annotations.png[activemq annotations]
If you need to check a sending of messages then you can use the `ExpectedMessage` annotation:
[source, java]
----
@SpringBootTest
@EnableActiveMqTest
public class SendMessageTest {@Autowired
private JmsTemplate jmsTemplate;@Test
@ExpectedMessage(queue = "test-queue", message = "123")
void testSend() {
jmsTemplate.convertAndSend("test-queue", "123");
}@TestConfiguration
public static class TestConfig {
@Bean
public Queue testQueue() {
return new Queue("test-queue");
}
}
}
----Also, you can assert the receiving of multiple messages:
[source, java]
----
@Test
@ExpectedMessages(queue = "test-queue", <1>
messagesFile = "/datasets/expected_messages.json") <2>
void testSendListOfMessages() {
// first type:
jmsTemplate.convertAndSend("test-queue", new Foo("123"));
// second type:
jmsTemplate.convertAndSend("test-queue", new Bar("AAA",1));
jmsTemplate.convertAndSend("test-queue", new Bar("BBB",2));
jmsTemplate.convertAndSend("test-queue", new Bar("CCC",3));
}
----
<1> queue name
<2> file with expected messages in JSON formatContent of the `expected_messages.json` :
[source,json]
----
{
"com.jupiter.tools.spring.test.activemq.extension.expected.Foo": [
{
"value":"123"
}
],
"com.jupiter.tools.spring.test.activemq.extension.expected.Bar":[
{
"name":"AAA",
"count":1
},
{
"name":"BBB",
"count":2
},
{
"name":"CCC",
"count":3
}
]
}
----## Embedded Web Server
Let's consider the next microservice based application:
image:./images/embedded-web.png[embedded web services tests]
You can test inter-service communication by the running an embedded
web server with a mocked external controller and send HTTP requests to this server.[source,xml]
----com.jupiter-tools
spring-test-web
0.2----
Let's test requesting to the template-service by the using of embedded server:
[source, java]
----
@EnableEmbeddedWebServerTest <1>
@RedirectRibbonToEmbeddedWebServer("template-service") <2>
class RedirectRibbonExtensionTest {@Autowired
private RestTemplate restTemplate;@Test
void testRedirect() {
// Act
String result = restTemplate.getForObject("http://template-service/templates/{template}",
String.class,
"balance-template");
// Assert
assertThat(result).isEqualTo("{user} balance = {value}");
}@TestConfiguration
public static class TestCfg {@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}@RestController
@RequestMapping("/templates")
public class TestApi {@GetMapping("/{template}")
public String getLength(@PathVariable("template") String template) {
return "{user} balance = {value}";
}
}
}
}
----
<1> bind the embedded server to an available TCP-port
<2> resolve the client name("template-service") to an embedded server urlIf you want to run different web servers in one test suite
then you need to use a different port to each server.
And you need to be sure that selected port is available.Annotation `EnableEmbeddedWebServerTest` bind a random available TCP port to the server.port property of the Spring Framework.
`RedirectRibbonToEmbeddedWebServer` redirects all requests from any ribbon
clients to embedded server, by default (if you don't set the value of this annotation).## Examples
https://github.com/jupiter-tools/spring-boot-extensions-demo