spring boot 1.4, spock and application.properties

2019-04-30 07:07发布

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?

2条回答
乱世女痞
2楼-- · 2019-04-30 07:49

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.

查看更多
beautiful°
3楼-- · 2019-04-30 07:51

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
    }
}
查看更多
登录 后发表回答