如何使用模拟服务和异步功能测试“ ViewModel”?

时间:2020-04-15 18:10:52

标签: flutter dart flutter-test

我正在尝试使用Flutter进行测试,但无法进行以下工作。

我有一个“ AuthViewModel”,该方法具有一个调用AuthServices方法的方法,该方法创建一个用户并返回该用户。如果创建了用户,则AuthViewModel中的变量“ isAuthentificated”设置为true,并通过ChangeNotifier通知视图。

在生产中,AuthServices类应连接到Firebase或自己的后端以创建用户。

出于开发和测试目的,我创建了一个MockAuthServices类(基于抽象类),该类实现了模拟方法来创建用户。

但是当我测试AuthViewModel时,测试未通过(isAuthentificated返回null)。

当我尝试调试测试时,有时会收到此消息:

Could not load source 'dart:async-patch/async_patch.dart': <source not available>.

所以,这是我的测试:

test('create User', () async {
      final authServices = AuthServicesMock();
      final authViewModel = AuthViewModel(authServices: authServices);
      authViewModel.createUserWithEmailAndPassword(
          email: 'user@test.com', password: 'p@ssw0rd');
      expectLater(authViewModel.isAuthentificated, true);
});

这是AuthViewModel:

class AuthViewModel with ChangeNotifiers {
    AuthViewModel({@required AuthBaseServices authServices}) : _authServices = authServices;

    final AuthBaseServices _authServices;

    bool _isAuthentificated;

    get isAuthentificated => _isAuthentificated;

    void setIsAuthentificated(bool isAuthentificated) {
        _isAuthentificated = isAuthentificated;
        notifyListeners();
    }

    void createUserWithEmailAndPassword(
      {@required String email, @required String password}) async {
        try {
          setIsBusy(true);
          await _authServices.createUserWithEmailAndPassword(
              email: email, password: password);
          setIsAuthentificated(true);
        } catch (e) {
          print(e);
        } finally {
          setIsBusy(false);
        }
    }
}

这是模拟服务:

class AuthServicesMock implements AuthBaseServices {

  AuthServicesMock();

  Future<User> testCreateUserWithEmailAndPassword(
      {String email, String password}) async {
      try {
          await Future<void>.delayed(Duration(seconds: 1));
          if (_userStore.keys.contains(email)) {
              throw 'Something went wrong';
          }
          _userStore[email] = {
              'uid': random.randomAlphaNumeric(10),
              'password': password,
          };
          final User user = _convertToUserClass(_userStore[email]);
          return user;
        } catch (e) {
          print(e);
          throw e;
        }
      }
}

编辑

当我将 await 放在此行前面的测试中时,它会起作用:

await authViewModel.createUserWithEmailAndPassword(
    email: 'user@test.com', password: 'p@ssw0rd');

但是我有这个警告:

'await' applied to 'StreamSubscription<User>', which is not a 'Future'.

感谢您的帮助,

罗曼

0 个答案:

没有答案