Search code examples
unit-testinggroovyspock

Does the spock test code not prevent the mistake of putting the generated instance as a parameter?


I am testing using the spock framework in groovy language. I want to test TestService, and TestService uses TestRepository as below code.

@Service
@RequiredArgsConstructor
public class TestService {

    private final TestRepository repository;

The test code I intended is to create the TestRepository as a mock object and put it in as a parameter, as shown below.

class SpockTest extends Specification {

    private TestRepository repository = Mock()

    private TestService target = new TestService(repository)

However, Spock cannot be checked during compile time even if the TestService is created and put as a parameter as shown in the code below.

class SpockTest extends Specification {

    private TestRepository repository = Mock()

    private TestService target = new TestService(target) // It doesn't prevent mistakes.

What I'm curious about is how Spock works, so is this possible? Or, I wonder if there is another way to prevent this mistake.


Solution

  • What do you mean it doesn't prevent mistakes? If you actually run any tests it will fail with a NullPointerException.

    What you are experiencing here is one of the drawbacks of a dynamic language, you are basically passing in null as the target property is not initialized yet. You could try adding @CompileStatic or @TypeChecked, but they don't work 100% with Spock, and it is generally not advisable to do so.

    You should add @NonNull to your code to prevent null being passed in, doing do will generate an explicit null check.

    @Service
    @RequiredArgsConstructor
    public class TestService {
    
        @NonNull
        private final TestRepository repository;