OEurix
OEurix

Reputation: 433

Spock: How to let static method which is not in the class under test return certain value?

I am using Spock with Groovy to test a class:

public class Animal {
    public void findAnimal() {
        findAnimalInZoo();     
    }

    private void findAnimalInZoo() {
        if (!isGoodWeather) {
            throw Exception;
        }
    }

    private boolean isGoodWeather() {
        return "good".equals(Weather.getWeather());
    }
}

and the Weather class:

public class Weather {
    public static String getWeather() {
        return instance.getWeather();
    }
}

Now in each test case for method findAnimal(), I want to specify the value returned when calling Weather.getWeather().

def "when it is good weather then expect no exception"() {
    setup:
    // What should I do for Weather.getWeather()?    
}

How could I do it?

Upvotes: 2

Views: 3703

Answers (1)

Luis Muñiz
Luis Muñiz

Reputation: 4811

If your production code is Java, then you can't use Spock mocks to mock static methods. If your production code is Groovy, you can use this:

GroovyMock(Weather, global: true)
Weather.getWeather() >> "good"

If you're stuck with Java, then you need to use Powermock or JMockit to achieve this.

def "when it is good weather then expect no exception"() {
    setup:
    PowerMockito.mockStatic(Weather)
    when(Account.getWeather()).thenReturn("good")
}

Reference: https://dzone.com/articles/mocking-static-methods-groovy

PEDANTRY WARNING I know you are not always in the position to control or improve the code you are testing, so take this advice with that caveat.

When you need to go to such lengths to test your code, your code is screaming at you, that it is poorly designed. Your code is very tightly coupled to the Weather class. It is impossible to switch it out for something else, unless you do tricks with the VM, by rewriting classes. This means not only that your test code can't do this, but that your production code is unnecessarily inflexible.

Upvotes: 6

Related Questions