我创建了一个springboot项目,该项目分为三个Maven模块,即域层,核心层(包含持久性和业务逻辑)和Web层。我尝试对存储库ProductRepository(位于核心层)进行单元测试
@RunWith(SpringRunner.class) // provide bridge between SpringBoot test features and JUnit, for usage of springboot tsting features
@DataJpaTest
class ProductRepositoryTest {
@Autowired
private TestEntityManager em;
@Autowired
private ProductRepository repository;
@Test
void shouldReturnProduct() {
// given
Product p = Product.builder().id(1).designation("Test").reference("TEST").unitPrice(150).build();
this.em.persistAndFlush(p);
// when
Product found = repository.findByReference(p.getReference());
// then
assertThat(found.getReference()).isEqualTo(p.getReference());
}
}
但是存储库总是实例化为null。我在Eclipse中将这个测试作为JUnit测试运行,并且得到了nullpointerexception。
这是我的pom.xml文件
<dependencies>
<!--<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
答案 0 :(得分:0)
这是您的示例的有效版本-希望对您有所帮助。我认为您自己的项目中可能会有一些冲突的配置或依赖项。 https://github.com/tndavidson/springbootjparepositorytest
答案 1 :(得分:0)
您说您尝试对控制器进行单元测试,但是您使用@RunWith(SpringRunner.class),它用于集成测试。此注释将启动完整的应用程序。您只想测试存储库。您可以做的是创建一个可以在单元测试中实现的抽象DAO。
public abstract class AbstractRepository<RepositoryType> {
RepositoryType repository;
private DBI dbi;
protected abstract RepositoryType createRepository(final DBI dbi);
@Before
public final void setUpDataSource() throws Exception {
final JdbcDataSource jdbcDataSource = new JdbcDataSource();
// DB_CLOSE_DELAY=-1 ==> h2 will keep its content as long as the vm lives otherwise the content of the database
// is lost at the moment the last connection is closed.
jdbcDataSource
.setURL("jdbc:h2:mem:play;MODE=MySQL;DB_CLOSE_DELAY=-1L;INIT=RUNSCRIPT FROM 'classpath:path/to/file/init_test.sql';");
final Flyway flyway = new Flyway();
flyway.setDataSource(jdbcDataSource);
flyway.setLocations("/path/to/locations");
flyway.migrate();
dbi = new DBI(jdbcDataSource);
runDbScript("/data.sql");
repository = createRepository(dbi);
}
private void runDbScript(final String scriptPath) throws Exception {
try (InputStreamReader reader = new InputStreamReader(AbstractDaoTest.class.getResourceAsStream(scriptPath),
Charsets.UTF_8); Handle h = dbi.open()) {
RunScript.execute(h.getConnection(), reader);
}
}
}
现在,您可以在测试类中覆盖createRepository方法。
public class ProductRepositoryTest() {
@Override
protected ProductRepository createRepository(Dbi dbi) { return new ProductRepository(dbi); }
@Test
public void testGetProductById() {
Product response = repository.getProductById(1);
assertThat(response).isEqualTo(someObject);
}
}
如果需要模拟对象的框架,则可以使用Mockito;如果需要模拟静态或void方法,则可以使用PowerMock。
希望这会有所帮助。
答案 2 :(得分:-1)
将这些注释添加到测试类中。
@SpringBootTest
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class,
DbUnitTestExecutionListener.class,
TransactionalTestExecutionListener.class })
public class YourTestClass {....