How much IDEA can help us with Java-Spock

Introduction

The other day, at the company, a topic like "What does the IDE refactoring tool do when writing in Java test Spock?" Came up, so I looked it up. Please let us know if there are any mistakes or stories like "I wish I could do this in such a case!"! !!

Setting up: Writing Java tests in Spock

Writing Java tests in another language in the first place?

JUnit is a well-known Java testing framework, but you may encounter some difficult cases when considering maintainability. Therefore, even for services implemented in Java, you have the option of writing test cases in other languages. There is a lot of controversy around here [^ 1], and one example is the topic of writing Java tests in Spock.

What is Spock

A testing framework implemented in Groovy. Groovy has some enthusiastic users [^ 2], for example Jenkins' father Kawaguchi said ["It's no longer possible not to write JUnit tests in Groovy"](http://d.hatena.ne. jp / kkawa / 2011212).

Spock makes full use of Groovy's features and allows you to write more concisely than JUnit. For writing Java code in Spock, see Qiita Articles and Books -with-spock) etc. are coming out, and I think that it will increase further in the future.

How much you can borrow the power of the IDE

Now, when writing Java tests in Groovy, the issue is how much the IDE can be on your side. Because Groovy is a dynamic language, it's easy to imagine situations where automatic method signature changes don't work [^ 3]. This time it is a report that I examined it. The IDE used this time is tried with IntelliJ IDEA 2016.3.4.

Java-Spock with IDEA

Code to use this time

This time, I will try various things using TDDBC github code.

Production code is Java


public class SampleOfJava {

    public String say() {
        return "Hello TDD BootCamp!";
    }

}

The test code is Groovy(Spock)


class SampleSpec extends Specification {

    def "should return 'Hello TDD BootCamp!' in Java"() {

        given:
        def sut = new SampleOfJava()

        when:
        String actual = sut.say()

        then:
        actual == 'Hello TDD BootCamp!'

    }

}

Method rename

First, let's rename a method that you will often use. Let's rename the say method. You can use shift + F6.

rename


    public String shout() { //I renamed it to shout
        return "Hello TDD BootCamp!";
    }

The test code was also renamed automatically.

        given:
        def sut = new SampleOfJava()

        when:
        String actual = sut.shout() //Renamed

        then:
        actual == 'Hello TDD BootCamp!'

First of all, there is no problem.

Signature changes

Next, try changing the signature. The refactoring screen opens with command + F6, so try adding multiple parameters as shown below.

Type Name
String addedString
Integer addedInteger

Of course, the signature of the production code has been changed.

Signature changes


    public String say(String addedString, Integer addedInteger) { //Add two arguments
        return "Hello TDD BootCamp!";
    }

The signature of the test code has also changed. But it's not very polite. .. ..

        when:
        String actual = sut.say(,) //Arguments have been added, but I feel like I want you to do something a little more

If you don't like this, it's a little better to include the Default value that you can enter on the refactoring screen earlier.

        when:
        String actual = sut.say("DEFAULT", i) //If you put the default value, it looks a little more like that

I'd like another voice, but let's do it.

Be careful when adding only one argument

I was trying and noticed a tricky part. That is when changing the signature and increasing the argument by only one </ b>. For example, when I increased the arguments with the refactoring tool as shown below, the production code changed.

Change signature (add only one argument)


    public String say(String anotherParameter) { //Arguments added
        return "Hello TDD BootCamp!";
    }

Is that the test code? ?? It was not changed.

        when:
        String actual = sut.say() //Arguments do not increase orz

I'm a songwriter because I can pass the test depending on how I write it. The reason for this is that in Groovy, when calling a method with one argument, even if the caller calls it without setting any arguments, null is automatically set and it is measured properly. [^ 4]. In other words, the previous code

        when:
        String actual = sut.say(null) //Null is automatically assigned

Is equivalent to. So, it seems that IDEA knows this and does not add the caller's argument with the momentum that "this is okay". (Maybe it's a bug) This is pretty scary.

Countermeasures

That's why it is a countermeasure,

  1. Enter the default parameter when refactoring
  2. Add @CompileStatic to the test class

I think there is. I've already touched on 1. so it's okay, but a little more about 2. Groovy is a dynamic language, but it also has the option to compile statically. That is the annotation @CompileStatic. If you add this, even if the refactoring system fails, you will get a compile error, so be aware. That said, it's not a good solution as the refactoring tool doesn't work.

Summary

In IDEA, when I went to Java-Spock environment,

--You can use frequently used refactoring tools such as renaming and changing signatures without any basic problems. --Note that changing the signature with one argument is tricky.

It was a story that I understood that. Personally, I highly recommend the Java-Spock configuration, but if you do, let's be careful about the details.

[^ 1]: It's a little old, but http://devtesting.jp/pekema/?0002%2FHotlinks is well organized. [^ 2]: Of course I am one of them. [^ 3]: The reason is that it is not decided whether the method of the signature that exists until the runtime is called. Since it can be metaprogrammed, it is conceptually possible that methods are added dynamically just before execution. [^ 4]: I completely forgot about it, but I wrote about it on Qiita a long time ago. http://qiita.com/PoohSunny/items/a1de52653d09133de4ad

Recommended Posts

How much IDEA can help us with Java-Spock
How can I efficiently fill an array with values?
How foreign keys can be saved even with nil