单元测试验证单个方法或类是否按预期工作。它还通过在进行新更改时确认现有逻辑是否仍然有效来提高可维护性。
通常,单元测试很容易编写,但可以在测试环境中运行。400默认情况下,这会在进行网络调用或 HTTP 请求时产生带有状态代码的空响应。为了解决这个问题,我们可以在每次发出 HTTP 请求时轻松使用 Mockito 返回虚假响应。Mockito 有各种用例,随着我们的进行,我们将逐步介绍这些用例。
在本教程中,我们将演示如何使用 Mockito 来测试 Flutter 代码。我们将学习如何生成模拟、存根数据以及对发出流的方法执行测试。让我们开始吧!
-
什么是 Mockito?
-
生成模拟和存根数据
-
项目结构概述
-
依赖注入
-
-
使用参数匹配器
-
在 Mockito 中创建假货
-
在 Flutter 中模拟和测试流
什么是 Mockito?
Mockito 是一个众所周知的包,它可以更轻松地生成现有类的假实现。它消除了重复编写这些功能的压力。此外,Mockito 有助于控制输入,因此我们可以测试预期的结果。
假设使用 Mockito 可以更轻松地编写单元测试,但是,如果架构不好,模拟和编写单元测试很容易变得复杂。
在本教程的后面,我们将学习如何将 Mockito 与模型-视图-视图模型 (MVVM) 模式一起使用,该模式涉及将代码库分成不同的可测试部分,例如视图模型和存储库。
生成模拟和存根数据
模拟是真实类的假实现。它们通常用于控制测试的预期结果,或者当真实类在测试环境中容易出错时。
为了更好地理解这一点,我们将为处理发送和接收帖子的应用程序编写单元测试。
项目结构概述
在开始之前,让我们将所有必要的包添加到我们的项目中。
dependencies: dio: ^4.0.6 # For making HTTP requests dev_dependencies: build_runner: ^2.2.0 # For generating code (Mocks, etc) mockito: ^5.2.0 # For mocking and stubbing
我们将使用 MVVM 和存储库模式,其中包括对存储库和视图模型的测试。在 Flutter 中,将所有测试放在test文件夹中是一个很好的做法,它与文件夹的结构非常匹配lib。
接下来,我们将通过附加到文件名来创建authentication_repository.dart和文件。这有助于测试运行者找到项目中存在的所有测试。authentication_repository_test.dart``_test
超过 20 万开发人员使用 LogRocket 来创造更好的数字体验了解更多 →
我们将通过创建一个名为AuthRepository. 顾名思义,这个类将处理我们应用程序中的所有身份验证功能。之后,我们将包含一个登录方法,该方法检查状态代码是否相等200并捕获身份验证时发生的任何错误。
class AuthRepository { Dio dio = Dio(); AuthRepository(); Future<bool> login({ required String email, required String password, }) async { try { final result = await dio.post( '<https://reqres.in/api/login>', data: {'email': email, 'password': password}, ); if (result.statusCode != 200) { return false; } } on DioError catch (e) { print(e.message); return false; } return true; } // ... } void main() { late AuthRepository authRepository; setUp(() { authRepository = AuthRepository(); }); test('Successfully logged in user', () async { expect( await authRepository.login(email: 'james@mail.com', password: '123456'), true, ); }); }
在上面的测试中,我们AuthRepository在 setup 函数中初始化了 。由于它将在每个测试和测试组之前直接在内部运行main,因此它将auth为每个测试或组初始化一个新的存储库。
接下来,我们将编写一个测试,期望登录方法返回true而不会抛出错误。但是,测试仍然失败,因为单元测试默认不支持发出网络请求,因此发