2019-04-04 17:00:56 -07:00
2019-05-05 17:39:50 -07:00
2019-04-04 17:00:56 -07:00
2019-04-04 17:00:56 -07:00
2019-04-04 17:00:56 -07:00
2019-05-06 15:12:07 -07:00

image:https://api.travis-ci.org/spring-projects/spring-boot-data-geode.svg?branch=master["Build Status", link="https://travis-ci.org/spring-projects/spring-boot-data-geode"]

[[about]]
== 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 https://geode.apache.org/[Apache Geode]
& https://pivotal.io/pivotal-gemfire[Pivotal GemFire] (SDG) applications.

This project was born from https://spring.io/projects/spring-data-gemfire[_Spring Data for Pivotal GemFire's_]
(https://github.com/spring-projects/spring-data-gemfire[@GitHub])
https://github.com/spring-projects/spring-data-gemfire/tree/2.1.6.RELEASE/src/test/java/org/springframework/data/gemfire/test[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
https://github.com/spring-projects/spring-boot-data-geode/tree/master/spring-geode-autoconfigure/src/test/java/org/springframework/geode/boot/autoconfigure[test suite for SBDG]
and the https://github.com/spring-projects/spring-session-data-geode/tree/master/spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire[test suite for SSDG]
to get a sense of how this project is used and works.

[[nutshell]]
== 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-tests]]
=== 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
[source,java]
----
@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
https://github.com/spring-projects/spring-test-data-geode/blob/master/spring-data-geode-test/src/test/java/org/springframework/data/gemfire/MockClientCacheApplicationIntegrationTests.java[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]]
=== 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
[source,java]
----
@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
https://github.com/spring-projects/spring-boot-data-geode/blob/master/spring-geode-autoconfigure/src/test/java/org/springframework/geode/boot/autoconfigure/security/ssl/AutoConfiguredSslIntegrationTests.java[example]
of a concrete client/server _Integration Test_ extending STDG's `ForkingClientServerIntegrationTestsSupprt` class.

Notice, too, that I am using SDG's
https://docs.spring.io/spring-data/geode/docs/current/reference/html/#bootstrap-annotation-config[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 https://github.com/spring-projects/spring-test-data-geode/issues/9[Issue #9] for more details.
This feature would be loosely based on, and similar to,
_Spring Boot_ https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html[Testing]
with _Test Slices_.

[[conclusion]]
=== 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!
Description
No description provided
Readme Apache-2.0 1.7 MiB
Languages
Java 90.8%
Groovy 8.8%
Shell 0.4%