【发布时间】:2021-06-24 11:01:31
【问题描述】:
问题
运行 mvn test 在 Mongo 存储库的单元测试中返回以下错误:
创建名为“my_package.infrastructure.mongo.repositories.UserRepositoryMongoImplTests”的 bean 时出错:通过字段“userRepository”表达的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'my_package.infrastructure.mongo.repositories.users.UserRepositoryMongoImpl' available
正如您在下面的代码中看到的那样,我确保将@Repository 注释添加到我的实现类(AKA UserRepositoryMongoImpl),我也尝试使用@Component 注释,但它不起作用。然后我尝试将@ComponentScan("my_package")注解添加到我的配置类中,但仍然没有成功。
代码
我正在使用Java 11、Spring Boot、JUnit 和 TestContainers。我的文件夹结构如下:
.
├── src/
│ ├── main/
│ │ └── java/
│ │ └── my_package/
│ │ ├── domain/
│ │ │ └── users/
│ │ │ ├── User.java
│ │ │ └── UserRepository.java
│ │ ├── infrastructure/
│ │ │ └── mongo/
│ │ │ └── repositories/
│ │ │ └── UserRepositoryMongoImpl.java
│ │ └── ApplicationConfig.java
│ └── test/
│ └── my_package/
│ └── infrastructure/
│ └── mongo/
│ └── repositories/
│ └── UserRepositoryMongoImplTests.java
└── pom.xml
UserRepository.java
public interface UserRepository {
public User findByUsername(String username);
public User save(User user);
public void delete(User user);
}
ApplicationConfig.java
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("my_package")
public class ApplicationConfig {
}
UserRepositoryMongoImpl.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import my_package.domain.users.User;
import my_package.domain.users.UserRepository;
@Repository
public class UserRepositoryMongoImpl implements UserRepository {
@Autowired
private MongoTemplate mongoTemplate;
private static final String COLLECTION_NAME = "users";
@Override
public User findByUsername(String username) {
return mongoTemplate.findOne(Query.query(Criteria.where("username").is(username)), User.class, COLLECTION_NAME);
}
@Override
public User save(User user) {
return mongoTemplate.save(user, COLLECTION_NAME);
}
@Override
public void delete(User user) {
mongoTemplate.remove(user, COLLECTION_NAME);
}
}
UserRepositoryMongoImplTests.java
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
import my_package.domain.users.User;
import my_package.infrastructure.mongo.repositories.users.UserRepositoryMongoImpl;
@Testcontainers
@DataMongoTest(excludeAutoConfiguration = {
EmbeddedDataSourceConfiguration.class
})
public class UserRepositoryMongoImplTests {
@Autowired
private UserRepositoryMongoImpl userRepository;
@Container
private MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.4.4"));
@BeforeEach
void mongoDbContainerStarting() {
mongoDBContainer.start();
System.setProperty("spring.data.mongodb.uri", mongoDBContainer.getReplicaSetUrl());
}
@AfterEach
void mongoDbContainerStoping() {
mongoDBContainer.stop();
}
@Test
public void shouldSaveValidNewUser() {
User user = new User("username123", "heuehueheuh");
user = userRepository.save(user);
assert(user.id() != null);
assert(user.username().equals("username123"));
assert(user.password().equals("heuehueheuh"));
}
}
最后: 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>br.nom.carneiro.carlos</groupId>
<artifactId>future_software_003-ws</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>my-project</name>
<description>Random description</description>
<properties>
<java.version>11</java.version>
<testcontainers.version>1.15.2</testcontainers.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<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>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mongodb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-guava</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>${testcontainers.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.8</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-asciidoctor</artifactId>
<version>${spring-restdocs.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
我之前查过的问题
- Unsatisfied dependency expressed through field 'clientRepository';
- UnsatisfiedDependencyException: Error creating bean with name
- Unsatisfied dependency expressed through field 'userRepository'
如果您能给我建议,我们将不胜感激。
编辑
我尝试手动创建 Bean,将以下代码添加到我的配置类中:
@Bean
public UserRepositoryMongoImpl userRepositoryMongoImpl() {
return new UserRepositoryMongoImpl();
}
然后我得到以下错误:
无法注册在类路径资源 [blablabla] 中定义的 bean 'userRepositoryMongoImpl'。已在文件 [blablabla] 中定义了具有该名称的 bean,并且已禁用覆盖。
这可能意味着通过 @Repository 注释正确声明了 bean,但由于某种原因 Spring 没有发现它可以注入到我的测试类中。
【问题讨论】:
标签: java spring-boot