spring boot 1.4, spock and application.properties
Asked Answered
T

2

6

I am trying to write some tests for my Spring Boot 1.4.0 with Spock and my application-test-properties file is not being picked up.

I have this in my gradle:

dependencies {

    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile 'org.codehaus.groovy:groovy-all:2.4.1'    
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') {
}

Then I have this in

/src/test/groovy/resources:

# JWT Key
jwt.key=MyKy@99

And finally my Spock test:

@SpringBootTest(classes = MyApplication.class, webEnvironment=SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource("application-test.properties")
public class TokenUtilityTest extends Specification {

    @Autowired
    private TokenUtility tokenUtility

    def "test a valid token creation"() {
        def userDetails = new User(username: "test", password: "password", accountNonExpired: true, accountNonLocked: true,
        );

        when:
        def token = tokenUtility.buildToken(userDetails)

        then:
        token != null
    }
}

Which is testing this class:

@Component
public class TokenUtility {

    private static final Logger LOG = LoggerFactory.getLogger( TokenUtility.class );

    @Value("${jwt.key}")
    private String jwtKey;

    public String buildToken(UserDetails user) {
        return Jwts.builder()
                        .setSubject(user.getUsername())
                        .signWith(SignatureAlgorithm.HS512, jwtKey)
                        .compact();
    }

    public boolean validate(String token) {
        try {

            Jwts.parser().setSigningKey(jwtKey).parseClaimsJws(token);
            return true;

        } catch (SignatureException e) {
            LOG.error("Invalid JWT found: " + token);
        }
        return false;
    }
}

I originally instantiated the TokenUtility on my test but the application-test.properties was never loaded (I am assuming since jwtKey was null). So I am trying @Autowired my class under test, but now that is null.

It looks like Spring Boot 1.4 changed a lot for testing, so perhaps I am not wiring this up correctly?

Thereafter answered 23/7, 2016 at 17:45 Comment(0)
I
7

There are several things wrong with your test code; first, your dependencies are bad - Spock 1.0 does not support @SpringBootTest annotation so no context will be initialized and no post-processing will be done, hence the null pointer exception: nothing will be autowired.

Support for that annotation was added in Spock 1.1, which is still release-candidate, so you'll have to use that:

dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.6.0'

    compile('org.codehaus.groovy:groovy')

    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.spockframework:spock-core:1.1-groovy-2.4-rc-1')
    testCompile('org.spockframework:spock-spring:1.1-groovy-2.4-rc-1')
    testCompile group: 'com.h2database', name: 'h2', version: '1.4.192'
}

Then, your path to the application-test.properties is wrong and should be /application-test.properties since it is in the root of the classpath:

@SpringBootTest(classes = DemoApplication.class, 
                webEnvironment = WebEnvironment.RANDOM_PORT)
@TestPropertySource("/application-test.properties")
public class TokenUtilityTest extends Specification {

    @Autowired
    TokenUtility tokenUtility

    def "test a valid token creation"() {
        def userDetails = new User("test", "password", Collections.emptyList());

        when:
        def token = tokenUtility.buildToken(userDetails)

        then:
        token != null
    }
}
Impetuosity answered 24/7, 2016 at 13:45 Comment(0)
G
4

I had the similar problem, but for me, the solution was to change double quotes ".." to single quotes '..' inside the @Value annotation when working with Spock. Please find the example below:

@Value('${jwt.key}')
private String jwtKey;

PS - This is not the exact answer to the question. I am posting this for someone who faces a similar problem like mine and ends up here.

Grapefruit answered 9/10, 2018 at 4:21 Comment(1)
Since spock uses groovy, double quotes are handled as a GString, and that is similar to SpEL so groovy tries to replace the placeholders with real variables. That's why the usage of single quotes is required, to avoid groovy look for the variables.Robbirobbia

© 2022 - 2024 — McMap. All rights reserved.