Azure Functions Mock MongoDB测试失败:@InjectMocks实例化报错
Azure Functions Mock MongoDB测试异常解决
问题场景
我正在开发Azure Functions,尝试通过Mock MongoDB进行测试,希望能成功运行测试。
遇到的异常
无法实例化类型为com.stellantis.cso.kpi.function.CsoKpiBlobTriggerFunction的@InjectMocks字段‘csoKpiBlobTriggerFunction’。您未在字段声明时提供实例,因此我尝试构造实例,但构造函数或初始化块抛出异常:因‘connectionString’为null,无法调用‘String.startsWith(String)’
测试代码
@Mock MongoCollection mockCollection; @Mock MongoClient mongoClient; @Mock MongoDatabase database; @InjectMocks CsoKpiBlobTriggerFunction csoKpiBlobTriggerFunction; @InjectMocks ExecutionContextMock executionContext; @SuppressWarnings("unchecked") @Test void TestRun() throws Exception { File file = new File("/src/test/resources/json/10Q3EG1421896.json"); byte[] arr = new byte[(int)file.length()]; Mockito.when(mongoClient.getDatabase(Mockito.anyString())).thenReturn(database); Mockito.when(database.getCollection(Mockito.anyString())).thenReturn(mockCollection); csoKpiBlobTriggerFunction.run(arr,"10Q3EG1421896.json",executionContext); //PowerMockito.whenNew(MongoClient.class).withArguments(Mockito.anyString()).thenReturn(mongoClient); //PowerMockito.whenNew(MongoClientURI.class).withArguments(Mockito.anyString(),Mockito.any()).thenReturn(Mockito.any()); //PowerMockito.whenNew(ConnectionString.class).withArguments("mongodb://").thenReturn(Mockito.any()); }
解决方案
问题根源
Mockito的@InjectMocks在自动实例化CsoKpiBlobTriggerFunction时,目标类的构造函数或初始化逻辑中使用了connectionString参数,但该参数未被初始化,导致调用String.startsWith()时抛出空指针异常。
修复步骤
- 手动实例化目标类:不要依赖
@InjectMocks自动创建实例,而是手动构造CsoKpiBlobTriggerFunction,传入非空的测试用connectionString和Mock的MongoClient。 - 修正依赖注入方式:确保
MongoClient通过构造函数注入,这样Mockito能正确替换为Mock实例;如果是字段注入,可使用反射工具设置Mock。 - 调整测试代码:移除不必要的
@InjectMocks,修正文件读取逻辑,添加必要的初始化步骤。
修改后的测试代码
@Mock MongoCollection mockCollection; @Mock MongoClient mongoClient; @Mock MongoDatabase database; @Mock ExecutionContext executionContext; CsoKpiBlobTriggerFunction csoKpiBlobTriggerFunction; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); // 假设目标类构造函数接收connectionString和MongoClient,传入测试用非空连接串 csoKpiBlobTriggerFunction = new CsoKpiBlobTriggerFunction("mongodb://localhost:27017/test-db", mongoClient); } @SuppressWarnings("unchecked") @Test void testRun() throws Exception { // 修正文件路径,避免根路径问题,用Files读取更可靠 File file = new File("src/test/resources/json/10Q3EG1421896.json"); byte[] arr = Files.readAllBytes(file.toPath()); Mockito.when(mongoClient.getDatabase(Mockito.anyString())).thenReturn(database); Mockito.when(database.getCollection(Mockito.anyString())).thenReturn(mockCollection); csoKpiBlobTriggerFunction.run(arr, "10Q3EG1421896.json", executionContext); // 可添加验证逻辑,确认Mongo操作被正确调用 // Mockito.verify(mockCollection, Mockito.times(1)).insertOne(Mockito.any()); }
额外提示
- 如果目标类使用字段注入
MongoClient,可通过ReflectionTestUtils.setField(csoKpiBlobTriggerFunction, "mongoClient", mongoClient)设置Mock实例。 - 测试文件路径不要以
/开头,避免跨环境路径问题。 - 用
Files.readAllBytes替代手动读取文件,更简洁且能正确处理IO异常。
内容的提问来源于stack exchange,提问作者Shaik Muzammil
相关产品推荐
相关产品推荐

