Spring Boot 测试不会自动装配所有依赖项
Posted
技术标签:
【中文标题】Spring Boot 测试不会自动装配所有依赖项【英文标题】:Spring boot test doesn't Autowire all dependencies 【发布时间】:2021-10-19 06:43:24 【问题描述】:我的测试场景中有一些令人困惑的错误。
我们想重构一个根本没有经过测试的应用程序。为确保重构后我们有相同的结果,我将为一个 Controller
类编写一些集成测试。
@RestController
@RequestMapping("/rfq")
public class RfqController
@Autowired
private RfqRepository rfqRepo;
@Autowired
private RfqDao rfqDao;
...
@PostMapping("/get")
public @ResponseBody BuyerRfqView getRFQ(@RequestBody SingleIdBody body)
int id = body.getId();
Optional<Rfq> rfq = rfqRepo.getById(id);
...
在这种情况下,我想使用 testcontainers 和 spring-boot-test
进行测试,一切正常,容器已启动并运行,应用程序启动至今。但问题是在运行时 spring-boot-test 在被测类中没有Autowire
rfqRepo。在 Testclass 中,每个依赖项都在 ComponentScan 或 EntityScan 中,并且存储库也被注入。我不知道为什么这不起作用。当测试运行时,我通过 rfqRepo 得到一个 Nullpointer Exception
...
这是测试类:
@SpringBootTest(classes = RfqController.class, webEnvironment =
SpringBootTest.WebEnvironment.RANDOM_PORT)
@ComponentScan(...)
@EnableJpaRepositories(...)
@EntityScan(...)
@EnableAutoConfiguration
@ActiveProfiles("local")
@Testcontainers
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class RfqControllerTest
@Container
private static OracleContainer database = new OracleContainer(
"oracleinanutshell/oracle-xe-11g:latest")
.withExposedPorts(1521, 5500)
.withPassword("...");
@InjectMocks
RfqController rfqController;
@DynamicPropertySource
static void databaseProperties(DynamicPropertyRegistry registry)
registry.add("spring.datasource.url", database::getJdbcUrl);
registry.add("spring.datasource.username", database::getUsername);
registry.add("spring.datasource.password", database::getPassword);
@BeforeEach
void setUp()
MockitoAnnotations.openMocks(this);
ScriptUtils.runInitScript(new JdbcDatabaseDelegate(database, ""), "ddl.sql");
@Test
void testGetRFQ()
BuyerRfqView result = rfqController.getRFQ(new SingleIdBody(176501));
Assertions.assertEquals(new BuyerRfqView(), result);
【问题讨论】:
如果我看到 EntityScan、ComponentScan 等。我总是质疑这是否正确?为什么父包中没有SpringBootApplication类以及下面的其他所有内容? 这是个好问题 :) ...它是一个古老的项目,因此由于历史原因 :)。 但不幸的是,当我没有使用 injectMocks 而是使用 Autowired 对其进行注释时,我遇到了另一个错误:ScopeNotActiveException 这看起来像是一个“简单”测试的很多注释。您可能需要检查 Spring Boot Test 切片,这些切片可以使设置工作量更小且更易于理解:stevenschwenke.de/springTestSlices 【参考方案1】:在 SpringBootTest 注解中,您仅使用 RfqController。这是测试期间唯一可用的类。
@SpringBootTest(classes = RfqController.class, webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)
因此,您必须添加测试所需的所有类。
【讨论】:
我是这么认为的,但不幸的是这并不能解决问题。它在运行时也为空 如果你删除“classes = RfqController.class”?以上是关于Spring Boot 测试不会自动装配所有依赖项的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin Spring Boot 单元测试 - 添加 @TestExecutionListeners 不会注入依赖项