Implementing Websockets Game Server with Scala and Akka Streams [Part 2/4]

Second part of server side implementation.

Implementing Websockets Game Server with Scala and Akka Streams [Part 1/4]

First part of server side implementation

Github Code Search - Programmers' Goldmine

Learning new language or framework can sometimes be a struggle. Traditional approach is to read documentation which explains the concepts, and provides simple examples. Sometimes that might be enough, but what those documentations are often lacking are some advanced examples and usages in real projects.

Coming across a problem which is not described in documentation, most people look for solution on stackoverflow (or dig through sources). However the framework you are using might not be in the game for long enough to fill stackoverflow with every question you come up with.

Have you ever been stuck with a problem and thought to yourself:

“I know someone must have solved this before! Why there is no stackoverflow answer to this problem?”

You are right - someone has probably already solved it. And it’s very likely the solution has been pushed to github. It’s just a matter of finding it. Programmers are more likely to solve the issues themselves rather than ask random people on the internet about it.

Github search code

Github search provides a way to query repos in a various ways. One of them is searching code. This is extremly powerful feature. Every line ever written by anybody can be found with simple queries. The “good” thing about github is that the private repos are not free, so there are many projects implicitly shared to public by people who just want to backup their code. This is a goldmine of information!

Examples

Below are some of the examples which I find github search code is handy for.

Learning new api

Have you ever been stuck with 3rd party api, and unable to find similar code snippets for your case?

I was recently in need to use akka streams to read a huge file and pass the results to another file instantly. The documentation regarding this topic is good but short and could provide more examples.

Github advanced search to the rescue. After few clicks I found an awesome piece of code that streams the csv file modifies it and dumps to another file!

filepaths_example

Finding projects using technologies you are interested in

Let’s say you want to learn Spring MVC, Hibernate and testing with Spock. You could go to the docs of each libraries, and learn them one by one… or just find a project which integrates all of them.

Most platforms have some kind of dependency management tools. In case of Java that is usually Maven which stores all dependencies information in pom.xml file.

You can therefore query keywords and filename to find the projects you are interested in:

spring hibernate spock filename:pom.xml

This method is also great if you are looking for projects to contribute to.

find_technology

Integrating with external services

Looking for a quick way to integrate with github api using your favourite language? No problem - just look for the repos with the api url and filter by language:

api.github.com language:scala

find_integrations

Configuration

It also wouldn’t hurt to take a look at configuration files of real big projects. This might be extremly helpful, particularly in case of immature frameworks.

Let’s take a look how to configure akka cluster. Such configuration should contain ClusterActorRefProvider keyword and reside in file with .conf extension (usually application.conf):

ClusterActorRefProvider extension:conf

find_configuration

Conclusion

Github search is underrated yet extremly powerful tool for learning new apis,solving issues and finding repos you might be interested in. This is a great way to quickly get started with new framework - finding code snippets that are similar to what you want to achieve has never been easier. It also makes you feel less alone with the issues you encounter - it’s very likely some has already solved them. Likewise, discovering interesting projects with this search engine is just a matter of minutes.

JShell - Java 9 interpreter (REPL) - Getting Started and Examples

Many compiled languages include tools (sometimes called REPL) for statements interpretation. Using these tools you can test code snippets rapidly without creating project.

Take Scala as an example. Compilation can sometimes take a long time, but using repl each statement is executed instantly! That’s great when you are getting started with the language. Each expression gives you returned value and it’s type - that’s very valuable information.

In java, instead, we have to create a test or main method which prints results and needs to be recompiled every time you make a change.

When?

JShell will be introduced in Java 9 realease. You can however get early access build on https://jdk9.java.net/.

Running

Once you downloaded jdk9 there is a jshell executable in a bin directory. I suggest running it in verbose (-v) mode for the first time:

kuba@kuba-laptop:~/repos$ jdk-9/bin/jshell -v
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro


jshell> 

You can go back to non verbose mode using /set feedback normal.

Default imports

By default you get a set of common imports:

jshell> /imports
|    import java.util.*
|    import java.io.*
|    import java.math.*
|    import java.net.*
|    import java.util.concurrent.*
|    import java.util.prefs.*
|    import java.util.regex.*

You can add your own any time.

Expressions

You can type any valid java expression, and it will tell you the returned value, it’s type and assign it to a variable:

jshell> 3+3
$1 ==> 6
|  created scratch variable $9 : int

jshell> $1
$1 ==> 6
|  value of $1 : int

Variables

It is possible to declare variables and name them. Once you do that they become visible in the scope.

jshell> int x=5
x ==> 5
|  created variable x : int

jshell> x
x ==> 5
|  value of x : int

Methods

You can also define methods and even replace them:

jshell> void helloJShell() { System.out.println("hello JShell"); }
|  created method helloJShell()

jshell> helloJShell();
hello JShell

jshell> void helloJShell() { System.out.println("wow, I replaced a  method"); }
|  modified method helloJShell()
|    update overwrote method helloJShell()

jshell> helloJShell()
wow, I replaced a  method

Commands

Aparat from language syntax you can execute jshell commands. Some of the most useful ones (/help to list all of them) are:

listing variables

jshell> /vars
|    int x = 0
|    double j = 0.5

listing methods:

jshell> /methods
|    printf (String,Object...)void
|    helloJShell ()void

The printf method is defined by default.

listing sources

jshell> /list
  14 : helloJShell();
  15 : void helloJShell() { System.out.println("wow, I replaced a  method"); }
  16 : helloJShell()

editing sources in external editor

jshell> /edit helloJShell

Opens external editor, and replaces helloJShell method.

Example use cases

After 20 years of Java without REPL one might wonder what scenarios are suitable for JShell. Here are some examples.

Veryfing return type

Remember the time you learned that dividing two integers in Java does not result in floating number? For some time I was convinced that both numerator and denominator have to be floating for a result to be floating too. Let’s test that:

jshell> 1/2
$1 ==> 0
|  created scratch variable $1 : int

jshell> 1.0/2
$2 ==> 0.5
|  created scratch variable $2 : double

jshell> 1/2.0
$3 ==> 0.5
|  created scratch variable $3 : double

jshell> 1.0f/2
$4 ==> 0.5
|  created scratch variable $4 : float

jshell> 1/2.0f
$5 ==> 0.5
|  created scratch variable $5 : float

Turns out only one of them has to be floating.

Testing Java niuanses

Did you know that comparing autoboxed integers references which values are from range -128 to 127 (inclusive) returns true (they are cached)? You can verify that with shell in a matter of seconds:

jshell> Integer i1 = 127
i1 ==> 127

jshell> Integer i2 = 127
i2 ==> 127

jshell> i1 == i2
$35 ==> true

jshell> Integer i2 = 128
i2 ==> 128

jshell> Integer i1 = 128
i1 ==> 128

jshell> i1 == i2
$38 ==> false

Formatting

Sometimes the logs need to be verbose and properly formatted. This is tedious task and usually leads to few recompile cycles which significantly slows us down. Imagine you forgot what was the format sign responsible for integers. You can quickly verify that:

Let’s try %i (integer):

jshell> printf("I got %i apple",1)
|  java.util.UnknownFormatConversionException thrown: Conversion = 'i'
|        at Formatter$FormatSpecifier.conversion (Formatter.java:2691)
|        at Formatter$FormatSpecifier.<init> (Formatter.java:2717)
|        at Formatter.parse (Formatter.java:2565)
|        at Formatter.format (Formatter.java:2507)
|        at PrintStream.format (PrintStream.java:977)
|        at PrintStream.printf (PrintStream.java:873)
|        at printf (#s8:1)
|        at (#51:1)

Oops, maybe %d (decimal) :

jshell> printf("I got %d apple",1)
I got 1 apple

Conclusion

JShell is a very useful tool for prototyping and testing Java code snippets. Even though it is not yet officially released I highly recommend checking it out. There is also a JShell Java api which allows you to evaluate JShell from java. Once the java 9 is out I bet there will be JShell integrations in most popualar IDEs - this will make using it even more handy.

Solid in practice - Liskov Substitution Principle

3rd video of the series. This time it’s all about Liskov substitution.

Solid in practice - Open Closed Principle

This is the second episode of the series. The screencast contains explanation of open closed principle.
It also gives an practical example of a class violating this principle and how to fix it.

Solid in practice - Single Responsibility Principle

The screencast contains explanation of single responsible principle.
It also gives an practical example of a class violating this principle and how to fix it.

Creating JVM language [PART 20] - Writing real application with Enkel

Sources

The project can be cloned from github repository.
The revision described in this post is 5afeaa64a7fb22fad7fe2c30ee440d9a3ff25337.

Playing cards drawing simulator

In the previous 19 posts I’ve been describing the process of creating my very first programming language. All that hard work I’ve put into it would seem pointless if I’d never used it for anything useful, right?

I came up with an idea of credit cards drawing simulator. The idea is to provide number of players and number of cards per player. As an output you get randomized collection of cards for each player. Just like in real games the cards are being removed from the stack when drawing.

Card class

Card {

    string color
    string pattern

    Card(string cardColor,string cardPattern) {
        color = cardColor
        pattern = cardPattern
    }

    string getColor() {
        color
    }

    string getPattern() {
        pattern
    }

    string toString() {
        return "{" + color + "," + pattern + "}"
    }
}

There is nothing fancy here. Just simple domain object. It is immutable representation of a playing card.

CardDrawer class

CardDrawer {
    start {
        var cards = new List() //creates java.util.ArrayList 
        addNumberedCards(cards) //calling method with 3 arguments (last 2 are default)
        addCardWithAllColors("Ace",cards) 
        addCardWithAllColors("Queen",cards)
        addCardWithAllColors("King",cards)
        addCardWithAllColors("Jack",cards)
        //Calling with named arguments (and in differnet order)
        //The last parameter (cardsPerPlayer) is ommited (it's default value is 5)
        drawCardsForPlayers(playersAmount -> 5,cardsList -> cards) 
    }

    addNumberedCards(List cardsList,int first=2, int last=10) {
        for i from first to last {  //loop from first to last (inclusive)
            var numberString = new java.lang.Integer(i).toString()
            addCardWithAllColors(numberString,cardsList)
        }
    }

    addCardWithAllColors(string pattern,List cardsList) {
        cardsList.add(new Card("Clubs",pattern))
        cardsList.add(new Card("Diamonds",pattern))
        cardsList.add(new Card("Hearts",pattern))
        cardsList.add(new Card("Spades",pattern))
    }

    drawCardsForPlayers(List cardsList,int playersAmount = 3,int cardsPerPlayer = 5) {
        if(cardsList.size() < (playersAmount * cardsPerPlayer)) {
            print "ERROR - Not enough cards" //No exceptions yet :)
            return
        }
        var random = new java.util.Random()
        for i from 1 to playersAmount {
            var playernumberString = new java.lang.Integer(i).toString()
            print "player " + playernumberString  + " is drawing:"
            for j from 1 to cardsPerPlayer {
                var dawnCardIndex = random.nextInt(cardsList.size() - 1)
                var drawedCard = cardsList.remove(dawnCardIndex)
                print "    drawed:" + drawedCard
            }
        }
    }
} 

Running

First we need to compile Card class (no multiple files compilation implemented yet). Once the Card is compiled CardDrawer is able to find it on classpath (providing we added current dir to classpath)

java -classpath compiler/target/compiler-1.0-SNAPSHOT-jar-with-dependencies.jar: com.kubadziworski.compiler.Compiler EnkelExamples/RealApp/Card.enk
java -classpath compiler/target/compiler-1.0-SNAPSHOT-jar-with-dependencies.jar:. com.kubadziworski.compiler.Compiler EnkelExamples/RealApp/CardDrawer.enk

kuba@kuba-laptop:~/repos/Enkel-JVM-language$ java CardDrawer 
player 1 is drawing:
    drawed:{Diamonds,Queen}
    drawed:{Spades,7}
    drawed:{Hearts,Jack}
    drawed:{Spades,4}
    drawed:{Hearts,2}
player 2 is drawing:
    drawed:{Diamonds,4}
    drawed:{Hearts,Ace}
    drawed:{Diamonds,Jack}
    drawed:{Spades,Queen}
    drawed:{Spades,King}
player 3 is drawing:
    drawed:{Diamonds,Ace}
    drawed:{Clubs,2}
    drawed:{Clubs,3}
    drawed:{Spades,8}
    drawed:{Clubs,7}
player 4 is drawing:
    drawed:{Spades,Ace}
    drawed:{Diamonds,3}
    drawed:{Clubs,4}
    drawed:{Clubs,6}
    drawed:{Diamonds,2}
player 5 is drawing:
    drawed:{Hearts,4}
    drawed:{Hearts,Queen}
    drawed:{Hearts,10}
    drawed:{Clubs,Jack}
    drawed:{Diamonds,8}

Great! This proofs that Enkel,though in early stage, can already be used for creating some real applications.

Goodbye Enkel

I had a really great time creating Enkel and sharing the whole process here. Writing code is one thing, but describing it in a way, that other people could understand it is another challenge itself.

I learned a lot during the process, and hope some other people benefited (or will benefit) from the series too.

Unfortunately this is the last post of the series. The project will however be continued, so keep track of it!

Creating JVM language [PART 19] - Replacing equals and compareTo with operators





Sources

The project can be cloned from github repository.
The revision described in this post is 7e6a08eaf4272cb07138fb1ef9d5c2bb7d300df8.

Comparing objects in Java

Comparing objects is one of the most surprising part of the language for Java’s newcomers. Diving into the code directly without any theoretical background, one might find himself very confused by the results.

Moreover there are some traps that make the whole concept feel not deterministic. Let’s take a look at this example:

Integer a = 15;
Integer b = 15;
boolean areEqual = a == b;

There is an implicit boxing using Integer.valueOf(15) which returns cached Integer object. Because the reference is the same areEqual is true

After executing the code above, beginner Java programmer might think to himself - “Great, I can compare objects with ==

The next day he decides to change the values:

Integer a = 155;
Integer b = 155;
boolean areEqual = a == b;

and all of the sudden areEqual is false because 155 is above caching threshold.

Strings are also traps. If you create one by explicitly calling new you get a new reference. On the other hand if you assign variable to the string value ( “ “ notation) you get a pooled object.

The problem with this is that most of the times (I’d say 99%) we are interested in comparing relation between objects, not the reference value. I really wish == meant relational equality, and < , > , <= , >= called compareTo.

Instead of wishing let’s just implement it then!

Implementing bytecode generation for ConditionalExpression

In Creating JVM language [PART 10] - Conditional statements I introduced a way to compare primitive objects. The post describes how the compare operators are created. The only thing that needs to be changed is bytecode generation step.

Basically we need check if the value is primitive or reference. If the object is reference then the equals or compareTo method calls are generated:

public class ConditionalExpressionGenerator {
     
    //Constructor and fields

    public void generate(ConditionalExpression conditionalExpression) {
        Expression leftExpression = conditionalExpression.getLeftExpression();
        Expression rightExpression = conditionalExpression.getRightExpression();
        CompareSign compareSign = conditionalExpression.getCompareSign();
        if (conditionalExpression.isPrimitiveComparison()) {
            generatePrimitivesComparison(leftExpression, rightExpression, compareSign);
        } else {
            generateObjectsComparison(leftExpression, rightExpression, compareSign);
        }
        Label endLabel = new Label();
        Label trueLabel = new Label();
        methodVisitor.visitJumpInsn(compareSign.getOpcode(), trueLabel);
        methodVisitor.visitInsn(Opcodes.ICONST_0);
        methodVisitor.visitJumpInsn(Opcodes.GOTO, endLabel);
        methodVisitor.visitLabel(trueLabel);
        methodVisitor.visitInsn(Opcodes.ICONST_1);
        methodVisitor.visitLabel(endLabel);
    }

    private void generateObjectsComparison(Expression leftExpression, Expression rightExpression, CompareSign compareSign) {
        Parameter parameter = new Parameter("o", new ClassType("java.lang.Object"), Optional.empty()); // #1 
        List<Parameter> parameters = Collections.singletonList(parameter);
        Argument argument = new Argument(rightExpression, Optional.empty());
        List<Argument> arguments = Collections.singletonList(argument);
        switch (compareSign) { // #2
            case EQUAL:
            case NOT_EQUAL:
                FunctionSignature equalsSignature = new FunctionSignature("equals", parameters, BultInType.BOOLEAN); // #3
                FunctionCall equalsCall = new FunctionCall(equalsSignature, arguments, leftExpression);
                equalsCall.accept(expressionGenerator); // #4
                methodVisitor.visitInsn(Opcodes.ICONST_1); 
                methodVisitor.visitInsn(Opcodes.IXOR); // #5
                break;
            case LESS:
            case GREATER:
            case LESS_OR_EQUAL:
            case GRATER_OR_EQAL:
                FunctionSignature compareToSignature = new FunctionSignature("compareTo", parameters, BultInType.INT); // #6
                FunctionCall compareToCall = new FunctionCall(compareToSignature, arguments, leftExpression);
                compareToCall.accept(expressionGenerator);
                break;
        }
    }

    private void generatePrimitivesComparison(Expression leftExpression, Expression rightExpression, CompareSign compareSign) {
        leftExpression.accept(expressionGenerator);
        rightExpression.accept(expressionGenerator);
        methodVisitor.visitInsn(Opcodes.ISUB); 
    }
}

There are few sections worth explanation:

#1
Equals method is declared in Object class as follows:

public boolean equals(Object obj) {
        return (this == obj);
}

Therefore the parameter needs to be an java.lang.Object. The name is irrelavant (o seems fine). There is no default value (Optional.empty)

#2
It’s mandatory to distinguish whether the equality (== or !=), or comparing (> < >= or <=) operators were used . We could use compareTo for equality operator too but not all Classes implement Comparable interface.

#3
As pointed out before equals method is named “equals” has one parameter of type java.lang.Object and returns primitive boolean value.

#4
Generate bytecode responsible for calling equals method. Take a look in CallExpressionGenerator class for more details on that.

#5
The equals returns true (1) if the objects are equal or false (0) if the objects are different. The primitives equality is calculated the other way around. The values are subtracted from each other. If the result is 0 it means values are equal, otherwise they are not. To make things compatible, false needs to be swapped with true. To do that I used XOR (Exclusive or) logical instruction. The compareTo method on the other hand is very similar to primitive comparison. It return 0 if equal too, so there is no need to make any changes.

#6
Creating call which represents compareTo call. compareTo was introduced before generics so it also takes java.lang.Object as a parameter, but returns int.

Example

The following Enkel class:

EqualitySyntax {

 start {
    var a = new java.lang.Integer(455)
    var b = new java.lang.Integer(455)
    print a == b
    print a > b
 }
}

decompiled into Java looks like this:

public class EqualitySyntax {
    public void start() {
        Integer var1 = new Integer(455);
        Integer var2 = new Integer(455);
        System.out.println(var1.equals(var2));
        System.out.println(var1.compareTo(var2) > 0);
    }

    public static void main(String[] var0) {
        (new EqualitySyntax()).start();
    }
}

As you can see == was sucesfully mapped to equals and > was mapped into compareTo.

JUnit vs Spock + Spock Cheatsheet

If you are not familiar with spock it is testing framework for Groovy and Java. It’s been stable for quite some time and I highly recommend you to check it out if you are annoyed by Junit and Java’s style of writing tests.

What’s wrong with JUnit + <some mocking framework> ?

The standard way of testing Java application is to use Junit and some mocking framework (Mockito,EasyMock, PowerMock etc.).

Java combined with those frameworks makes it rather hard to write and read tests in medium and large sizes projects:

  • You cannot set title for a test (Junit5 introduces this feature but it is still in alpha). Instead you have to name your method in a ridiculous way like ‘shouldAddToCartIfItemIsAvailaibleAndTheLimitIsNotExceededAnd…..’.
  • The intent of the test is blurred by all those Java and mocking framework verbosity like Collections.singletonList()’s,replay’s,verify’s or any(MyAwesomeAbstractFactoryBaseClass.class)’s and many more.
  • There is no good way to separate sections responsible for different phases (given,when,then). Some people use comments to mark those sections but I think it’s even worse than not having them at all.
  • Java is certainly not easy language for building “expected” objects - everything is so verbose. Once again - it hides the intent of a test.
  • Parametrizied tests are kinda weird too. They must be stored in fields, and you can only have one set of them per test class.
  • Since parametrized test are not simple you usually
    write gazillion of separate methods - each covering different case, or even worse skip some cases hoping noone will notice :).

If tests are hard to write we usually think of them as something painful and start to neglect them. Avoiding or delaying writing tests leads to the situation where application cannot be trusted anymore. We then become afraid of making any changes because other part of the app might break in some bizarre way.

It shouldn’t be this way. Test should be easy and fun to write. After all they are like a cherry on top, proving that the features are implemented correctly.

In my opinion the most important responsibility of the test is to be as most readable as possible. Business changes to the project are introduced all the time. If we change something in the application we have to change test too (unless you’re applying open-closed principle, which I’ve never heard of anyone successfully adapting :D). If tests are hard to read there is a big problem.

On the other hand - these are just my opinion, who am I to judge? Do you feel similar about this topic or is it just me? If you disagree, or have some objections leave a comment!

Spock

Spock is both testing and mocking framework. What’s more it extends Junit runner so it can be runned by the tools you used for your tests before.

The best thing about Spock is that it’s basically a DSL (domain specifing language) for writing tests. It’s based on Groovy and is designed particularly testing. It introduces some syntax features just for that purpose. You may therefore expect some neat stuff in it (which is indeed correct).

Groovy is kinda like a scripting version of Java - simple, less verbose but retains all the power of JVM.

Benefits from using spock over Junit + mocking framework:

  • Groovy - less verbose than Java
  • Additional syntax features designed for testing
  • Integrated stubbing and mocking
  • Extends Junit runner
  • Easy parametrized testing
  • Labels for all phases of a test (given,when,then…)
  • Ability to document methods easily (unlike weird Junit method’s name pattern)
  • Many more specified below

Cheatsheet

This cheatsheet contains the most useful spock features regarding testing Java applications. Most of this is copy-paste from official spock documentation. I compiled it while I was learning the framework to have all information in one place. I figure out since it’s already compiled why not share it on a blog too.

Basics

Specification template

class MyFirstSpecification extends Specification {
  // fields
  // fixture methods
  // feature methods
  // helper methods
}

Fixture Methods

def setup() {}          // run before every feature method
def cleanup() {}        // run after every feature method
def setupSpec() {}     // run before the first feature method
def cleanupSpec() {}   // run after the last feature method

Blocks order

    given: //data initialization goes here (includes creating mocks)
    when: //invoke your test subject here and assign it to a variable
    then: //assert data here
    cleanup: //optional
    where: //optional:provide parametrized data (tables or pipes) 
      

or

    given:
    expect: //combines when with then
    cleanup: 
    where:

Blocks

Junit comparison

Spock JUnit
Specification Test class
setup() @Before
cleanup() @After
setupSpec() @BeforeClass
cleanupSpec() @AfterClass
Feature Test
Feature method Test method
Data-driven feature Theory
Condition Assertion
Exception condition @Test(expected=…​)
Interaction Mock expectation (e.g. in Mockito)

Data Driven Testing

Data Tables

class Math extends Specification {
    def "maximum of two numbers"(int a, int b, int c) {
        expect:
        Math.max(a, b) == c

        where:
        a | b | c
        1 | 3 | 3   //passes
        7 | 4 | 4   //fails
        0 | 0 | 0   //passes
    }
}

Input data can also be seperated with expected parameters using ||:

    where:
    a | b || c
    3 | 5 || 5
    7 | 0 || 7
    0 | 0 || 0

Unrolling

A method annotated with @Unroll will have its rows from data table reported independently:

@Unroll
def "maximum of two numbers"() { ... }

With unroll

maximum of two numbers[0]   PASSED
maximum of two numbers[1]   FAILED

Math.max(a, b) == c
    |    |  |  |  |
    |    7  0  |  7
    42         false

Without unroll

We have to figure out which row failed manually

maximum of two numbers   FAILED

Condition not satisfied:

Math.max(a, b) == c
    |    |  |  |  |
    |    7  0  |  7
    42         false

Data Pipes

Right side must be Collection, String or Iterable.

where:
a << [3, 7, 0]
b << [5, 0, 0]
c << [5, 7, 0]

Multi-Variable Data Pipes

where:
[a, b, c] << sql.rows("select a, b, c from maxdata")
where:
row << sql.rows("select * from maxdata")
// pick apart columns
a = row.a
b = row.b
c = row.c

Ignore some variable

where:
[a,b] << [[1,2,3],[1,2,3],[4,5,6]]
[a, b, _, c] << sql.rows("select * from maxdata")

Combine data tables,pipes and assignments

where:
a | _
3 | _
7 | _
0 | _

b << [5, 0, 0]

c = a > b ? a : b

Unrolled method names parameters

def "#person is #person.age years old"() { ... } // property access
def "#person.name.toUpperCase()"() { ... } // zero-arg method call

Interaction Based Testing

Mocking

Create mock

Mocks are Lenient (return default value for undefined mock calls)

Subscriber subscriber = Mock()
def subscriber2 = Mock(Subscriber)

Using mock

def "should send messages to all subscribers"() {
    when:
    publisher.send("hello")

    then:
    1 * subscriber.receive("hello") //subsriber should call receive with "hello" once.
    1 * subscriber2.receive("hello")
}

Cardinality

1 * subscriber.receive("hello")      // exactly one call
0 * subscriber.receive("hello")      // zero calls
(1..3) * subscriber.receive("hello") // between one and three calls (inclusive)
(1.._) * subscriber.receive("hello") // at least one call
(_..3) * subscriber.receive("hello") // at most three calls
_ * subscriber.receive("hello")      // any number of calls, including zero
                                     // (rarely needed; see 'Strict Mocking')

Constraints

Target

1 * subscriber.receive("hello") // a call to 'subscriber'
1 * _.receive("hello")          // a call to any mock object

Method

1 * subscriber.receive("hello") // a method named 'receive'
1 * subscriber./r.*e/("hello")  // a method whose name matches the given regular expression
                                // (here: method name starts with 'r' and ends in 'e')

Argument

1 * subscriber.receive("hello")     // an argument that is equal to the String "hello"
1 * subscriber.receive(!"hello")    // an argument that is unequal to the String "hello"
1 * subscriber.receive()            // the empty argument list (would never match in our example)
1 * subscriber.receive(_)           // any single argument (including null)
1 * subscriber.receive(*_)          // any argument list (including the empty argument list)
1 * subscriber.receive(!null)       // any non-null argument
1 * subscriber.receive(_ as String) // any non-null argument that is-a String
1 * subscriber.receive({ it.size() > 3 }) // an argument that satisfies the given predicate
                                          // (here: message length is greater than 3)                                

Specify mock calls at creation

class MySpec extends Specification {
    Subscriber subscriber = Mock {
        1 * receive("hello")
        1 * receive("goodbye")
    }
}

Group interactions

with(mock) {
    1 * receive("hello")
    1 * receive("goodbye")
}

Stubbing

Stubs do not have cardinality (matches invokation anyTimes)

def subsriber = Stub(Subscriber)
...
subscriber.receive(_) >> "ok"

Whenever the subscriber receives a message, make it respond with ‘ok’

Returning different values on sucessive calls

subscriber.receive(_) >>> ["ok", "error", "error", "ok"]
subscriber.receive(_) >>> ["ok", "fail", "ok"] >> { throw new InternalError() } >> "ok"

Extensions

@Ignore(reason = "TODO")
@IgnoreRest
@IgnoreIf({ spock.util.environment.Jvm.isJava5()) })
@Requires({ os.windows })
@Timeout(5)
@Timeout(value = 100, unit = TimeUnit.MILLISECONDS)
@Title("This tests if..."
@Narrative("some detailed explanation")
@Issue("http://redmine/23432")
@Subject