java - 测试 MongoDB 存储库:使用名称创建 bean 时出错:没有符合条件的 bean 类型
问题描述
问题
运行mvn test
在 Mongo 存储库的单元测试中返回以下错误:
创建名称为“my_package.infrastructure.mongo.repositories.UserRepositoryMongoImplTests”的 bean 时出错:通过字段“userRepository”表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的“my_package.infrastructure.mongo.repositories.users.UserRepositoryMongoImpl”类型的合格 bean
正如您在下面的代码中看到的那样,我确保将@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
用户存储库.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>
我之前查过的问题
- 通过字段“clientRepository”表示的不满足的依赖关系;
- UnsatisfiedDependencyException:创建具有名称的 bean 时出错
- 通过字段“userRepository”表示的不满足的依赖关系
如果你能给我建议,任何意见将不胜感激。
编辑
我尝试手动创建 Bean,将以下代码添加到我的配置类中:
@Bean
public UserRepositoryMongoImpl userRepositoryMongoImpl() {
return new UserRepositoryMongoImpl();
}
然后我收到以下错误:
无法注册在类路径资源 [blablabla] 中定义的 bean 'userRepositoryMongoImpl'。已在文件 [blablabla] 中定义了具有该名称的 bean,并且禁用了覆盖。
这可能意味着通过注解正确声明了 bean @Repository
,但由于某种原因,Spring 没有发现它可以注入我的测试类。
解决方案
我解决了在@SpringBootApplication
课堂上添加以下注释的问题@ComponentScan(basePackages = {"my_package.infrastructure.mongo"})
:原来我的 ComponentScan 注释是错误的并且在错误的类中。
我在阅读 NoSuchBeanDefinitionException 问题的答案时得出了这个结论:no qualifying bean of type。
推荐阅读
- python - 来自 Gerrit Rest Api 的双重 GET 请求
- sql-server - 使用具有正确格式的 bcp.exe 创建 XML 文件
- while-loop - 计数器在 jmeter 中循环控制器的每次迭代结束时未重置
- java - 由于空指针异常,代码将无法工作
- http - 为什么 https 和 www 在同一个 URL 中?
- python - 在python中获取QListView中选定项目的索引
- python - 是否可以在附魔中传递多个字典?
- json - 如何在python中将以下字符串转换为JSON
- cluster-analysis - 通过不同指标评估的 k-means 的性能
- python - 我的代码有一个 if-else 条件,但我认为代码没有检查 if 条件,而是直接进入 else 条件