I have a Spring Boot application, and I am trying to use @Autowired in a JUnit 5 extension. However, I cannot get it to work. (The @Autowired field is null.) Can anybody help?
Below is code that demonstrates the problem I'm having (the important parts are SomeExtension and SomeTest. As written, mvn test causes the test to fail in beforeEach. Sorry if I'm including too much.
src/test/java/somepackage/SomeExtension.java:
package somepackage;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SomeExtension implements BeforeEachCallback {
@Autowired
SomeBean bean;
@Override
public void beforeEach(ExtensionContext context) {
assertNotNull(bean);
}
}
src/test/java/somepackage/SomeTest.java:
package somepackage;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SomeExtension.class)
class SomeTest {
@Test
void nothingTest() {
}
}
src/main/java/somepackage/SomeBean.java
package somepackage;
import org.springframework.stereotype.Component;
@Component
public class SomeBean {
}
src/main/java/somepackage/MainClass.java
package somepackage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MainClass {
public static void main(String[] args) {
SpringApplication.run(MainClass.class, args);
}
}
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fooGroupId</groupId>
<artifactId>barArtifactId</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<!-- Don't include Junit 4 -->
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!--
This is copied from https://junit.org/junit5/docs/current/user-guide/#running-tests-build-maven
This allows the surefire plugin to be able to find Junit 5 tests, so `mvn test` works.
-->
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
I'm also having similar issues with @Value. If the solution also works for that, it would be great.
Thank you.
Autowiring using property type. Allows a property to be autowired if exactly one bean of property type exists in the container. If more than one exists, it's a fatal exception is thrown, which indicates that you may not used byType autowiring for that bean.
By default, the @Autowired annotation implies that the dependency is required. This means an exception will be thrown when a dependency is not resolved. You can override that default behavior using the (required=false) option with @Autowired .
if there is exactly one bean of the property type in the container. If there is more than one, a fatal exception is thrown, and this indicates that you may not use byType autowiring for that bean. If there are no matching beans, nothing happens; the property is not set.
Also note that we can wire other spring beans in our jUnit test classes using @Autowired annotation.
JUnit 5 extensions can not operate on other extensions, just on test classes.
So...
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SomeExtension implements BeforeEachCallback {
@Autowired
SomeBean bean;
@Override
public void beforeEach(ExtensionContext context) {
assertNotNull(bean);
}
}
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SomeExtension.class)
class SomeTest {
@Test
void nothingTest() {
}
}
... can not work. This would:
public class SomeExtension implements BeforeEachCallback {
@Override
public void beforeEach(ExtensionContext context) {
// [...]
}
}
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SomeExtension.class)
class SomeTest {
@Autowired
SomeBean bean;
@Test
void nothingTest() {
}
}
If you can explain why you need a bean in your extension, we may be able to help you find a fix for that, too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With