Skip to content
A Spring-based Test Framework supporting Unit and Integration testing for Spring Boot applications using Spring Data with either Apache Geode or Pivotal GemFire.
Branch: master
Clone or download
Latest commit 58a61d5 May 24, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.mvn/wrapper URL Cleanup. Apr 5, 2019
gradle Upgrade to Gradle 5.4.1. May 6, 2019
spring-data-gemfire-test
spring-data-geode-test
.gitignore Update .gitignore to ignore the Gradle build/ directory. Apr 3, 2018
.travis.yml
Jenkinsfile Declare build a SUCCESS by default. May 18, 2018
LICENSE URL Cleanup. Apr 5, 2019
README.adoc Add concrete Unit and Integration Test class examples. May 8, 2019
build.gradle
gradle.properties Prepare next development iteration. May 13, 2019
gradlew Install the Gradle Wrapper (gradlew) version 4.6. Apr 2, 2018
gradlew.bat Install the Gradle Wrapper (gradlew) version 4.6. Apr 2, 2018
mvnw Switch HTTP URLs to HTTPS. Apr 5, 2019
mvnw.cmd Switch HTTP URLs to HTTPS. Apr 5, 2019
pom.xml Prepare next development iteration. May 13, 2019
settings.gradle Reorganize project as a multi-module project with modules for both Sp… May 18, 2018

README.adoc

Build Status

Spring Test Framework for Apache Geode & Pivotal GemFire

The STDG project is a Spring Data module, building on the core Spring Framework’s TestContext, used to write Unit and Integration Tests when building Spring Data for Apache Geode & Pivotal GemFire (SDG) applications.

This project was born from Spring Data for Pivotal GemFire’s (@GitHub) test framework. This test framework is used in SDG’s test suite to test the proper function of Apache Geode & Pivotal GemFire in a Spring context.

For several years now, users have asked for a way to test their Apache Geode & Pivotal GemFire based, Spring applications reliably and easily, when writing Unit and Integrations tests.

Additionally, STDG was created to consolidate the testing efforts, lessons learned, and knowledge of effectively testing all Spring for Apache Geode/Pivotal GemFire projects: Spring Boot for Apache Geode & Pivotal GemFire (SBDG) and Spring Session for Apache Geode & Pivotal GemFire (SSDG).

Eventually, STDG will replace the SDG test classes so that tests and testing efforts are consistent across all Spring projects for Apache Geode/Pivotal GemFire: SDG, SBDG and SSDG.

This (relatively) new project is still under development and will have documentation, examples and an extensive test suite once complete.

In the meantime, you can review the test suite for SBDG and the test suite for SSDG to get a sense of how this project is used and works.

STDG in a Nutshell

Until proper documentation has been provided, this very short and simple tutorial will hopefully give you a better idea of how this project is used.

Unit Testing with STDG

We all write tests, right? TDD style? ;-)

As we begin to write tests, we typically start with Unit Tests since they are designed to test the subject in isolation, without dependencies, to get feedback quickly, i.e. "Is my logic correct?"

It is often common in Unit Tests to mock dependencies since the test makes an assumption that the dependencies "work as designed". During Unit Testing, it does not matter whether or not the dependencies actually work as expected (that is the function/job/purpose of the Integration Tests), just that they have a contract and our application components, the "Subject Under Test" (SUT), honors that contract and uses the external dependencies correctly. Essentially we asserting that the interactions between our application components and external dependencies is correct and results in the desired outcome.

Well, it is, or should be, no different when you are using Apache Geode or Pivotal GemFire.

For instance, you might want to mock that your Data Access Object (DAO) performs the proper interactions on a GemFire/Geode Region, performing the right CRUD operations, making sure the right (OQL) Queries are executed for the Use Case or business function/workflow being performed by the application.

In this case, we don’t care whether the Region is real or not, that an OQL Query is actually well formed and would actually execute properly, performantly and return the correct results. We would "mock" the Regions' behavior in this case to make sure that our DAO interactions with the Region are correct, that it handles the translation of Exceptions or other Error conditions, that it transforms values to/from the backend data store (i.e. Region), and so on. That is how you properly test the subject.

To support Unit Testing with Apache Geode or Pivotal GemFire in a Spring context, STDG provides the @EnableGemFireMockObjects annotation. If you want to use GemFire/Geode Mock Objects (e.g. a "mock" Region) rather than a "live" Region, than you simply only need to annotate your test configuration with @EnableGemFireMockObjects.

For example:

Unit Test with GemFire/Geode Mock Objects
@RunWith(SpringRunner.class)
@ContextConfiguration
class ExampleUnitTestClass {

  // test case methods here

  @EnableGemFireMockObjects
  @ClientCacheApplication
  @EnableEntityDefinedRegions(clientRegionShortcut = ClientRegionShortcut.LOCAL)
  static class TestConfiguration { }

}

In the example above, @EnableGemFireMockObjects creates "mocks" for the ClientCache and all Regions identified and created by the @EnableEntityDefinedRegions(..) annotation. There are no "live" GemFire/Geode objects when "mocking" is enabled.

Here is 1 example of a concrete Unit Test in action, using STDG’s @EnableGemFireMockObjects annotation.

It really is that simple!

Tip
Mocking GemFire/Geode objects outside a Spring context is possible, but beyond the scope of this guide for the time being.

Integration Testing with STDG

You should write many more Unit Tests than Integration Tests to get reliable and fast feedback. This is a no brainer and software development 101.

However, Unit Tests do not completely take the place of Integration Tests, either. Both are necessary, as are perhaps other forms of testing (e.g. Functional Testing, Acceptance Testing, Smoke Testing, Performance Testing, Concurrency Testing, etc).

For instance, you should verify that the (OQL) Query you just constructed, maybe even generated, is well-formed and yields the desired results, is performant, and all that jazz. You can only reliably do that by executing the (OQL) Query against an actual GemFire/Geode Region with a properly constructed and deliberate data set.

This sort Integration Test does not have a complex arrangement, and can be performed simply by removing or disabling the @EnableGemFireMockObjects annotation in our previous example above.

However, other forms of Integration Testing might require a more complex arrangement, such as client/server integration tests.

For instance, you may want to test that a client receives all the events from the server to which it has explicitly registered interests. For this type of test, you need to have a (1 or more) GemFire/Geode server(s) running, and perhaps even a few clients.

Ideally, you want to fork a GemFire/Geode server JVM process in the Integration Test class requiring a server instance.

Once again, STDG comes to the rescue.

For example:

Client/Server Integration Test
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = GeodeClientTestConfiguration.class)
class ExampleIntegrationTestClass extends ForkingClientServerIntegrationTestsSupport {

  @BeforeClass
  public static void startGemFireServer() {
    startGemFireSever(GeodeServerTestConfiguration.class);
  }

  // test case method here

  @CacheServerApplication
  @EnableEntityDefinedRegions
  static class GeodeServerTestConfiguration {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext applicationContext =
          new AnnotationConfigApplicationContext(GeodeServerTestConfiguration.class);

        applicationContext.registerShutdownHook();
    }
  }

  @ClientCacheApplication
  @EnableEntityDefinedRegions
  static class GeodeClientTestConfiguration { }

}

First we extend the STDG provided ForkingClientServerIntegrationTestsSupport class. Then, we define a JUnit @BeforeClass static setup method to fork our GemFire/Geode JVM process using the GeodeServerTestConfiguration.class specifying exactly how the server should be configured and finally we create the matching GeodeClientTestConfiguration class to configure and bootstrap our JUnit, Spring TestContext based test, which acts as the client.

STDG takes care of coordinating the client & server, using random connection ports, etc. You simply just need to provide the configuration of the client and server as required by your application and test case(s).

Here is 1 example of a concrete client/server Integration Test extending STDG’s ForkingClientServerIntegrationTestsSupprt class.

Notice, too, that I am using SDG’s Annotation-based configuration model (e.g. CacheServerApplication, @EnableEntityDefinedRegions) to make the GemFire/Geode configuration even easier.

If you are using SBDG with this project, then some of the annotations are not even required (e.g. ClientCacheApplication).

When SBDG & STDG are combined, the power you have is quite extensive.

Note
Through the Integration Test support provided by and in STDG is relatively simple, this is also not quite yet the ideal way for writing client/sever Integration Tests. Eventually, we want to include an annotation, something like @ClientServerIntegrationTest(serverConfigClass = GeodeServerTestConfiguration.class), the equivalent to @EnableGemFireMockObjects for Unit Testing, to make configuration and testing of client/server applications that much easier. See Issue #9 for more details. This feature would be loosely based on, and similar to, Spring Boot Testing with Test Slices.

Conclusion

Anyway, we hope this has intrigued your interests and gets you started for now. Ideas, contributions, or other feedback is most welcomed.

Thank you!

You can’t perform that action at this time.