Since the post on Test Driven Development in DukeScript we know that DukeScript
is excellent when it comes to testing the UI behavior. However a typical
DukeScript application not only shows a UI, but also talks to a server.
This post is going to explain how easy is to mock such server communication
and make it fully unit testable.
@OnReceive with Plain Text
The DukeScript network communication is typically done with the
help of the @OnReceive
annotation that is provided as part of HTML/Java API.
It has been carefully designed to express intentions with as little Java
code as possible. Handling an asynchronous REST call and processing
its result fits in the following twelve lines:
The question, of course, is how do we test the behavior of such a method without really
connecting to the server? Luckily, every API in the DukeScript ecosystem comes
with an SPI which allows us to create a mock implementation and inject it in the Test:
The test basically checks whether -after calling method obtainMessage- the
application connects to the specified server URL and then uses the reply as a
value of its own message property.
To do that check (and to avoid connecting to a real server), we register our own
implementation of the SPI interface Transfer.
The implementation is registered into the BrwsrCtx,
and our Data instance is then bound to the context. As a result our
MockTrans implementation is injected into the Data instance and
used whenever the instance needs to perform a network operation.
Our MockTrans implementation handles only the loadJSON method
and checks its input parameters and also verifies the correctness of the passed in URL.
The mock implementation then completes the network operation by
calling the notifySuccess method. Usually the call to notifySuccess
is asynchronous, but for unit testing, it is more handy to make it synchronous. Like this we can
check the value of data.getMessage() immediately after returning from
the obtainMessage call.
Testing network communication is so easy with DukeScript!
Type-safe Access to Received JSON Data
As we discussed in
our blog entry on type-safe parsing
the biggest power of the DukeScript APIs is enabling
type-safe access to JSON structures. Rather than accepting simple text
we can define a Repo model class and let the @OnReceive method do
the parsing automatically. Here is the improved example that defines an additional
Repo model:
How can we mock such a network communication with parsing in a test? The
approach is the same, but we need to also implement the extract method
and make sure the value passed to notifySuccess can be understood by
the extract method as well. Here is the code of our new testing method:
We use List to hold the data passed from notifySuccess and extract it
in the extract method after verifying that we are really queried for
two properties in the order specified when declaring the Repo model class.
And that’s all. The rest of the test remains the same.
Dealing with JSON Arrays
Of course, if you click at the real REST URL
you find out it returns an array of JSON objects. So we should also
modify our code to accept a list of Repo instances:
What needs to be changed in the test? Almost nothing: just call the
notifySuccess method with an array of objects! The internal infrastructure
will recognize the array and do the necessary processing itself:
Done. We can now use TDD to
verify the network communication of our DukeScript based application in
unit tests.
Good luck creating your own portable, robust applications in Java!