Writing assertions using the nice fluent API of AssertJ is a joy. Besides some of the basic assertions like isEqualTo
AssertJ also has specific assertions for specific types. For example if we want write an assertion to check if a String
value starts or ends with an expected value we can use the startsWith(String)
or endsWith(String)
methods. If we don’t care that a character is upper or lower case we can also use startsWithIgnoringCase(String)
or endsWithIgnoringCase(String)
. Each of the methods also has a counterpart method to check the String
value doesn’t start or end with an expected value. For example we can use doesNotStartWith(String)
to assert a value does not start with the expected value.
Continue reading →
AssertJ has many useful methods to write assertions using a fluid API. If we want to test the toString()
method implementation of an object we can of course invoke the toString()
method inside an assertThat
expression and check with the assert method isEqualTo(String)
the value. But AssertJ can make that easier so we don’t have to invoke toString()
method ourselves. We can use the assert method hasToString(String)
on the object we defined in the assertThat
expression and specify our expected value as argument to the method. If we want to assert the toString()
method doesn’t return an expected value we can use the assert method doesNotHaveToString(String)
.
Continue reading →
The living room was dimly lit, with the only source of light being the glow of the computer screen in front of a young woman.
She sat cross-legged on the floor, headphones on, typing away furiously.
Her grandfather, a wiry old man with a thick beard, sat on the couch behind her, watching her work with a sense of pride and wonder.
Continue reading →
GINQ (Groovy-INtegerate Query) is part of Groovy since version 4. With GINQ we can use SQL-like queries to work with in-memory data collections. If we want to sort the data we can use orderby
followed by the property of the data we want to sort just like in SQL we can use order by
. By default the sort ordering is ascending and null
values are put last. We can change the sort ordering by specifying in desc
with the orderby
clause. Or to make the ascending order explicitly we use the statement in asc
. Each of asc
and desc
also can take an argument to specify how we want null
values to be sorted. The default way is to keep null
values last in the ordering. If we want to make this explicit we use nullslast
as argument to asc
or desc
. To have null
values in the sorted result first we use the argument nullsfirst
.
Continue reading →
Since Groovy 4 we can use SQL like queries on in-memory collections with GINQ (Groovy-Integrated Query). GINQ provides some built-in aggregate functions like min
, max
, sum
and others. One of these functions is median
. With median
we can get the value that is in the middle of the sorted list of values we want to calculate the median for. If the list has an uneven number of elements the element in the middle is returned, but if the list has an even number of elements the average of the two numbers in the middle is returned.
In the following example we see the use of the median
function with GINQ:
Continue reading →
Groovy supports a tuple type. A tuple is an immutable object to store elements of potentially different types. In Groovy there is a separate Tuple
class based on how many elements we want to store in the tuple. The range starts at Tuple0
and ends with Tuple16
. So we can store a maximum of 16 elements in a Groovy tuple.
Each of the classes has a constructor that takes all elements we want to store. But the Tuple
class also has static factory methods to create those classes. We can use the tuple
method and based on how many elements we provide to this method we get the corresponding Tuple
object.
Continue reading →
In a previous blog post we learned how to use DataVariable
and DataVariables
to test asynchronous code. Spock also provides PollingConditions
as a way to test asynchronous code. The PollingConditions
class has the methods eventually
and within
that accept a closure where we can write our assertions on the results of the asynchronous code execution. Spock will try to evaluate conditions in the closure until they are true. By default the eventually
method will retry for 1 second with a delay of 0.1 second between each retry. We can change this by setting the properties timeout
, delay
, initialDelay
and factor
of the PollingConditions
class. For example to define the maximum retry period of 5 seconds and change the delay between retries to 0.5 seconds we create the following instance: new PollingConditions(timeout: 5, initialDelay: 0.5)
.
Instead of changing the PollingConditions
properties for extending the timeout we can also use the method within
and specify the timeout in seconds as the first argument. If the conditions can be evaluated correctly before the timeout has expired then the feature method of our specification will also finish earlier. The timeout is only the maximum time we want our feature method to run.
Continue reading →
Testing asynchronous code needs some special treatment. With synchronous code we get results from invoking method directly and in our tests or specifications we can easily assert the value. But when we don’t know when the results will be available after calling a method we need to wait for the results. So in our specification we actually block until the results from asynchronous code are available. One of the options Spock provides us to block our testing code and wait for the code to be finished is using the classes DataVariable
and DataVariables
. When we create a variable of type DataVariable
we can set
and get
one value result. The get
method will block until the value is available and we can write assertions on the value as we now know it is available. The set
method is used to assign a value to the BlockingVariable
, for example we can do this in a callback when the asynchronous method support a callback parameter.
The BlockingVariable
can only hold one value, with the other class BlockingVariables
we can store multiple values. The class acts like a Map
where we create a key with a value for storing the results from asynchronous calls. Each call to get the value for a given key will block until the result is available and ready to assert.
Continue reading →
The log
function in the dw::Core
module allows to log a value or an expression. The function returns the input unchanged. This means we can wrap our code with the log
function and the code is still executed as is, but also logged in a system log. As an extra argument we can specify a String
value that will be a prefix to the expression value in the logging output. The fact that the input is also returned makes it very easy to add the log
function to our DataWeave expressions.
Continue reading →
A .mvn
directory in the root of our project can contains some useful extras. For example we can set default Maven options or Java VM options when we run a Maven command. We can also define Maven extensions we want to add to the Maven classpath using the file extensions.xml
in the .mvn
directory. The Maven extension we want to add can be referenced using a groupId
, artifactId
and version
inside an <extension>
element. We can define one or more extensions within the parent element extensions
. Once we have defined the extension and run Maven the extension is added to classpath of Maven itself.
Continue reading →