Thursday, June 14, 2018

Spock 1.2 Annotations for Spring Integration Testing


@SpringBean, @SpringSpy, and @UnwrapAopProxy are new annotations in Spock 1.2 that make it easier to inject mocks into the Spring context when doing Integration testing. These can greatly simplify your code from using a @TestConfiguration approach, though there are some drawbacks too. If you're not familiar with the Spock 1.1 @TestConfiguration method, take a look at the original Spock Spring Integration blog post from Derek Eskens.


Let's start with the easiest new annotation @SpringBean. This annotation will tell Spock to add the mocked bean into the Spring test context. To use it you will need to explicitly create the Mock() and include a defined type (instead of using `def`)


Similarly, @SpringSpy will wrap a Spy around the bean that Spring creates and puts into the context. For most cases it is simple to just use @SpringSpy in place of @SpringBean.

It becomes more complicated when trying to Spy a Spring AOP Proxied bean. @Validated services are one type of proxied object, as Spring wraps the class to perform the validation.

Without unwrapping the AOP proxy, the error you see in Spock will be very puzzling:


@UnwrapAopProxy is a new Spock 1.2 annotation for easily unwrapping the proxy to use the spied object.

While @SpringBean and @SpringSpy make it very easy to Integration Test, the one drawback is that Spring will create a new test context for each test and will not try to cache and reuse the context between tests. So for very large applications with many tests this can be quite slow. In those cases you will still need to resort to using a reusable @TestConfiguration class.

Manual AOP Proxy unwrapping

In those cases, you will need to manually unwrap the AOP proxy for spying. This can be done using AopTestUtils.getUltimateTargetObject() from the spring-test package:

Spock 1.2-SNAPSHOT

As of this blog post writing in May 2018, Spock 1.2 is still a SNAPSHOT and has not been fully released yet. So to pull in the snapshot you'll need to use the snapshot repo in your gradle (or maven) file

Hopefully this was a helpful intro to the new annotations available in Spock 1.2. You can try them out in a full source repo with tests by cloning the github repo

Cross-published on the Object Partners blog:

Wednesday, May 02, 2018

Logical GWT client testing with Spock


GWT - Google Web Toolkit may not be as heavily used as it once was 5-10 years ago, though many enterprise teams and legacy projects are still using the technology. While we can easily use Spock to test our other Java and Groovy projects, and even to test some parts of GWT, the client-side portion of GWT that executes native Javascript is not quite so simple.

The GWT project does provide testing patterns for unit and integration tests, however they are a bit cumbersome to work with. The framework supplied option is to extend GWTTestCase which runs the test in an HtmlUnit headless browser, a valid but slow procedure.

Another nice option is to use GwtMockito which provides Mockito mocks for the core client-side GWT classes. This works great if you stay in a JUnit + Mockito world. But what if we would like to use Spock? It's only logical.

Replicating all of the inner classes that are mocked out by GwtMockito would be a great thing to have for Spock, but unfortunately is not currently available. Also duplicating this effort seems inefficient for a project on its last legs.

The solution provided here leverages the goodness of using GwtMockito from within Spock (as opposed to JUnit). And really, it is fairly simple to use this pattern:

1) Setup Mocks, and Initialize GwtMockito.
- This involves normal Spock mocks for any services used by the file under test.
- GwtMockito initialization follows the pattern for usage outside of a JUnit test runner
- We also instantiate our class under test, the GwtSpockWidget, but wrapping it as a Spy

2) Spock Spy wrapper
- The Spock Spy wrapper shown above requires usage of an as-of-this-date(2018-04-30) unpublished version of Spock 1.2
- It uses a fix to allow spying instantiated objects that lack an empty constructor
- Grab it from the snapshot repo like this:

3) Simple test of @UIField element
- GwtMockito auto mocks the @UIField elements with Mockito mocks. As such, we need to verify them Mockito-style as seen on Line 16 below:

4) Test object under test with Spock Spy
- To verify that an action takes place somewhere else in the widget, we can easily validate an internal call through the Spy:

This was just a quick run-thru to get you started on "modern" GWT client testing with Spock and GwtMockito. It is much faster than spinning up the default GWTTestCase container, you don't have to stumble through JUnit assertions, and best of all it uses Spock. Precisely.

Full test source:

Cross-published on the Object Partners blog: