Jebuselwyn Martin
Jebuselwyn Martin

Reputation: 573

Unit Testing with GemFire - best practices

For unit-testing Services which use GemFire, we are planning to include GemFire 'Regions' in the test-context to avoid mocking and have any dependency on the Gemfire server. What are the best-practices / tools available to enable this?

Theoritically, below is the option we are planning:

Service --> GemFire(embedded in test-context)

To bootstrap context, ContextConfiguration: add a test-applicationContext which has reference to the gfe-cache xml.

Junits will load the test-context and bootstrap the Regions, now we can fire the create/fetch/delete using GemFire and validate the results.

Upvotes: 0

Views: 2218

Answers (1)

John Blum
John Blum

Reputation: 7981

What you are describing are Integration Tests and something Spring Data GemFire does almost exactly as you describe, albeit a bit more directly (i.e. injecting GemFire Regions or perhaps other GemFire components directly into test classes). For instance have a look at the GemFireTemplateIntegrationTest class along with it's associated Spring (XML) config.

This makes sense for Spring Data GemFire to use GemFire components directly in tests. Although, this is perhaps less than ideal in an actual application test suite, primarily because I believe in good Separation of Concerns and providing appropriate facades around the dependencies my application uses.

In other words, and as you alluded to above, having the following (traditional n) tiers in the application...

UI -> Service -> DAO

The Service tier is pure business logic and rules and any interactions (CRUD, Querying, Function execution, etc) with any data store (GemFire/Geode included) is done so via the DAO.

This makes mocking the DAO very easy so that you can focus on the point of the Service tests, to test the business logic and rules independently of how the underlying data store behaves.

Of course, it is important to have Integration Tests to ensure the proper interactions with your underlying data store, such as GemFire/Geode, if only to ensure proper transactional behavior, or that your OQL (query) statements are well formed.

But, there are many options when it comes to implementing your DAO.

  1. You can inject the Region into your DAO(s) and perform operations (CRUD, Queries, etc) directly on the Region.

  2. If you are using Spring Data GemFire, you might prefer to shield your DAO(s) from direct use of the GemFire/Geode API using the GemfireTemplate (in case of interface breaking changes introduced by GemFire/Geode, or to wrap GemFire/Geode Exceptions in Spring's convenient and consistent (across data stores) Exception class hierarchy, which is useful if you ever swap out data stores). See here for more details.

  3. Lastly (but not least), you can use Spring Data GemFire's extension of Spring Data Common's Repository abstraction with support for GemFire/Geode. This makes implementing DAOs (a.k.a. Repositories) as simples as defining an interface that extends GemfireRepository.

You choice depends on the level of abstraction you prefer and each choice will slightly change how you approach your Integration Testing.

As one final tidbit, this does not preclude you from still writing true Unit Tests either.

Spring Data GemFire employs a custom test framework (with mocks and stubs) to simplify Unit Tests involving GemFire components (such as Regions, AEQs, Gateways, etc). This "custom test framework" is rooted in the GemfireTestApplicationContextInitializer and the associated GemfireTestBeanPostProcessor. If you follow the logic through you will begin to see how it works.

This custom test framework is very useful for testing the validity of the GemFire components created and initialized using SDG's XML namespace. However, it is becoming increasingly popular to put configuration meta-data, even for GemFire/Geode components into Spring config now, something I am looking to enhance/simplify further in Spring Data GemFire 1.9.

In addition, I hope to, at some point, work that I have already begun, to uplift and refactor Spring Data GemFire's custom test framework into a separate, top-level Spring project extension for Spring Data GemFire as this sort of question has been asked a lot.

Anyway, hopefully this gives you some ideas how to best approach tests for you application in a simple, concise and consistent manner.

Cheers!

Upvotes: 1

Related Questions