Flutter Mocktail测试:如何捕获未在when方法中抛出的异常?
Flutter Mocktail测试:如何捕获未在when方法中抛出的异常?
嘿,我来帮你搞定这个测试里的异常捕获问题~
你现在遇到的核心问题是:makeRequest 方法会在仓库返回null时主动抛出异常,但测试里直接await这个方法的话,异常会直接导致测试失败——因为测试框架没收到「我们预期这个异常抛出」的信号。下面给你两种靠谱的解决办法:
方法一:用expectLater验证异常抛出(推荐)
这是Flutter测试框架官方推荐的异步异常验证方式,它会等待异步操作完成,并检查是否抛出了预期的异常:
test('When api returns null, should throw exception', () async { // stub when(() => repository.get(requestParams)) .thenAnswer((_) => Future.value(null)); // 验证方法会抛出指定类型的异常 await expectLater( () => usecase.makeRequest(requestParams), throwsA(isA<Exception>()), ); // 验证仓库方法确实被调用了一次 verify(() => repository.get(requestParams)).called(1); });
这种方式最简洁,而且能清晰表达测试意图:我们就是要确认这个方法在仓库返回null时会抛出异常。
方法二:手动用try-catch捕获异常(适合检查异常细节)
如果你还想验证异常的具体内容(比如错误消息是不是"Whoops"),可以用try-catch手动捕获后再做断言:
test('When api returns null, should throw exception', () async { // stub when(() => repository.get(requestParams)) .thenAnswer((_) => Future.value(null)); Exception? caughtException; try { await usecase.makeRequest(requestParams); } catch (e) { caughtException = e as Exception; } // 断言异常确实被捕获到,且错误消息符合预期 expect(caughtException, isNotNull); expect(caughtException?.toString(), contains('Whoops')); // 验证仓库方法的调用次数 verify(() => repository.get(requestParams)).called(1); });
为什么原来的代码会失败?
你之前直接await usecase.makeRequest(requestParams),当方法抛出异常时,测试框架会把这个未捕获的异常当成测试错误,而不是预期行为。所以必须通过上述方式明确告诉测试框架:这个异常是我们故意要验证的结果。
备注:内容来源于stack exchange,提问作者José Carlos
相关产品推荐
相关产品推荐

