Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在尝试抛出自定义异常时,Mockito的行为很奇怪。

在尝试抛出自定义异常时,Mockito的行为很奇怪。
EN

Stack Overflow用户
提问于 2018-09-11 05:38:24
回答 2查看 2.6K关注 0票数 2

试图使用Mockito测试我的BLoC,BLoC使用存储库类进行服务器调用,如果用户未经过身份验证,服务器调用函数将抛出自定义异常。

但是,当我试图对存储库函数进行存根以引发自定义异常时,测试只会失败,出现以下错误:

代码语言:javascript
运行
AI代码解释
复制
sunapsis Authorization error (test error): test description

package:mockito/src/mock.dart 342:7                                     PostExpectation.thenThrow.<fn>
package:mockito/src/mock.dart 119:37                                    Mock.noSuchMethod
package:sunapsis/datasource/models/notifications_repository.dart 28:37  MockNotificationRepository.getNotificationList
package:sunapsis/blocs/notification_blocs/notification_bloc.dart 36:10  NotificationBloc.fetchNotifications
test/blocs/notification_blocs/notification_bloc_test.dart 53:48         main.<fn>.<fn>.<fn>
===== asynchronous gap ===========================
dart:async                                                              scheduleMicrotask
test/blocs/notification_blocs/notification_bloc_test.dart 53:7          main.<fn>.<fn>

这就是我的BLoC代码的样子:fetchNotifications函数调用存储库函数并处理响应和错误。有两个catchError块,一个处理AuthorizationException大小写,另一个处理其他异常。以不同的方式处理AuthorizationException,因为它将用于设置应用程序的登录状态。

notification_bloc.dart

代码语言:javascript
运行
AI代码解释
复制
import 'dart:async';

import 'package:logging/logging.dart';
import 'package:rxdart/rxdart.dart';
import 'package:sunapsis/datasource/dataobjects/notification.dart';
import 'package:sunapsis/datasource/models/notifications_repository.dart';
import 'package:sunapsis/utils/authorization_exception.dart';

class NotificationBloc {
  final NotificationsRepository _notificationsRepository;

  final Logger log = Logger('NotificationBloc');
  final _listNotifications = PublishSubject<List<NotificationElement>>();
  final _isEmptyList = PublishSubject<bool>();
  final _isLoggedIn = PublishSubject<bool>();

  Observable<List<NotificationElement>> get getNotificationList =>
      _listNotifications.stream;

  Observable<bool> get isLoggedIn => _isLoggedIn.stream;

  Observable<bool> get isEmptyList => _isEmptyList.stream;

  NotificationBloc({NotificationsRepository notificationsRepository})
      : _notificationsRepository =
            notificationsRepository ?? NotificationsRepository();

  void fetchNotifications() {
    _notificationsRepository
        .getNotificationList()
        .then((List<NotificationElement> list) {
          if (list.length > 0) {
            _listNotifications.add(list);
          } else {
            _isEmptyList.add(true);
          }
        })
        .catchError((e) => _handleErrorCase,
            test: (e) => e is AuthorizationException)
        .catchError((e) {
          log.shout("Error occurred while fetching notifications $e");
          _listNotifications.sink.addError("$e");
        });
  }
  void _handleErrorCase(e) {
     log.shout("Session invalid: $e");
     _isLoggedIn.sink.add(false);
     _listNotifications.sink.addError("Error");
 }
}

这就是我的存储库代码的样子:

notifications_repository.dart

代码语言:javascript
运行
AI代码解释
复制
import 'dart:async';

import 'package:logging/logging.dart';
import 'package:sunapsis/datasource/dataobjects/notification.dart';
import 'package:sunapsis/datasource/db/sunapsis_db_provider.dart';
import 'package:sunapsis/datasource/network/api_response.dart';
import 'package:sunapsis/datasource/network/sunapsis_api_provider.dart';
import 'package:sunapsis/utils/authorization_exception.dart';

/// Repository class which makes available all notifications related API functions
/// for server calls and database calls
class NotificationsRepository {
  final Logger log = Logger('NotificationsRepository');
  final SunapsisApiProvider apiProvider;
  final SunapsisDbProvider dbProvider;

  /// Optional [SunapsisApiProvider] and [SunapsisDbProvider] instances expected for unit testing
  /// If instances are not provided - default case - a new instance is created
  NotificationsRepository({SunapsisApiProvider api, SunapsisDbProvider db})
      : apiProvider = api ?? SunapsisApiProvider(),
        dbProvider = db ?? SunapsisDbProvider();

  /// Returns a [Future] of [List] of [NotificationElement]
  /// Tries to first look for notifications on the db
  /// if notifications are found that list is returned
  /// else a server call is made to fetch notifications
  Future<List<NotificationElement>> getNotificationList([int currentTime]) {
    return dbProvider.fetchNotifications().then(
        (List<NotificationElement> notifications) {
      if (notifications.length == 0) {
        return getNotificationsListFromServer(currentTime);
      }
      return notifications;
    }, onError: (_) {
      return getNotificationsListFromServer(currentTime);
    });
  }
}

函数getNotificationsListFromServer应该抛出AuthorizationException,该AuthorizationException应该通过getNotificationList传播。

这是前面提到的错误失败的测试用例:

代码语言:javascript
运行
AI代码解释
复制
test('getNotification observable gets error on AuthorizationException',
    () async {
  when(mockNotificationsRepository.getNotificationList())
      .thenThrow(AuthorizationException("test error", "test description"));
  scheduleMicrotask(() => notificationBloc.fetchNotifications());
  await expectLater(
      notificationBloc.getNotificationList, emitsError("Error"));
});

这就是自定义异常的样子:

authorization_exception.dart

代码语言:javascript
运行
AI代码解释
复制
class AuthorizationException implements Exception {
  final String error;

  final String description;

  AuthorizationException(this.error, this.description);

  String toString() {
    var header = 'sunapsis Authorization error ($error)';
    if (description != null) {
      header = '$header: $description';
    }
    return '$header';
  }
}

PS:当我测试我的存储库类和抛出自定义异常的函数时,这些测试都通过了。

代码语言:javascript
运行
AI代码解释
复制
test('throws AuthorizationException on invalidSession()', () async {
  when(mockSunapsisDbProvider.fetchNotifications())
      .thenAnswer((_) => Future.error("Error"));
  when(mockSunapsisDbProvider.getCachedLoginSession(1536333713))
      .thenAnswer((_) => Future.value(authorization));
  when(mockSunapsisApiProvider.getNotifications(authHeader))
      .thenAnswer((_) => Future.value(ApiResponse.invalidSession()));
  expect(notificationsRepository.getNotificationList(1536333713),
      throwsA(TypeMatcher<AuthorizationException>()));
});

上述测试通过并按预期工作。

我是一个新的大学毕业生,我的第一份全职工作,我可能做错了什么。我将非常感谢任何反馈或帮助,一切都有帮助。谢谢你调查这个问题。

EN

回答 2

Stack Overflow用户

发布于 2018-09-12 08:20:56

我认为您使用了错误的TypeMatcher类。您需要使用测试框架中的,而不是颤振框架中的。

代码语言:javascript
运行
AI代码解释
复制
import 'package:flutter_test/flutter_test.dart';
import 'package:matcher/matcher.dart';

class AuthorizationException implements Exception {
  const AuthorizationException();
}

Future<List<String>> getNotificationList(int id) async {
  throw AuthorizationException();
}

void main() {
  test('getNotification observable gets error on AuthorizationException',
  () async {
    expect(getNotificationList(1536333713),
      throwsA(const TypeMatcher<AuthorizationException>()));
  });
}
票数 1
EN

Stack Overflow用户

发布于 2021-10-19 13:11:53

您正在使用thenThrow抛出一个异常,但是由于模拟的方法返回一个未来,所以应该使用thenAnswer

这个测试应该是这样的:

代码语言:javascript
运行
AI代码解释
复制
test('getNotification observable gets error on AuthorizationException', () async {

  // Using thenAnswer to throw an exception:
  when(mockNotificationsRepository.getNotificationList())
      .thenAnswer((_) async => throw AuthorizationException("test error", "test description"));

  scheduleMicrotask(() => notificationBloc.fetchNotifications());
  await expectLater(notificationBloc.getNotificationList, emitsError("Error"));
});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52277270

复制
相关文章
使用wget命令下载Google drive上的文件
此处的文件是指公开的文件,不需要输入密码也不需要登录Google drive即可获取的文件。
烤粽子
2021/07/07
9.1K0
用 Cyberduck下载 / 上传 Google Drive 大文件
用Google Colab训练模型时,可以将训练好的权重模型存储到Google Drive上,很方便。但是,将模型权重下载下来就特别麻烦。另外,上传bert模型和数据集也特别困难。尝试了一些方法,最好的方法是使用Cyberduck(就是下面这个鸭子),传输稳定,并且可以断点续传。
SeanCheney
2020/05/09
4.2K0
用 Cyberduck下载 / 上传 Google Drive 大文件
如何用命令行下载Google Drive上的共享文件?
如果共享文件非常大,比如10多个G,这个时候简单的用网上推荐的 wget方法是没办法下载的,最终只是下载了一个html内容。因为当文件太大的时候谷歌会需要先跳转页面审查一下有没有病毒,然后再开始下载。
marsggbo
2022/05/11
4.4K0
如何用命令行下载Google Drive上的共享文件?
Google drive copy File
Creates a copy of a file and applies any requested updates with patch semantics. Try it now.
拿我格子衫来
2022/01/24
4560
rclone挂载Google Drive
元旦在土区成功购买Google one 2T之后,就着手开始用rclone挂载Google Drive
行 者
2023/10/20
8790
如何使用命令行将数据上传到Google Drive?
要想命令行将数据上传到Google Drive,这里推荐一个工具,叫 rclone。
marsggbo
2022/05/11
1.1K0
如何从Google Play下载Android应用的APK安装文件?
有时候可能因为种种原因,你无法直接在手机上连接Google Play来下载应用(比如说你设备不兼容,说你所在地区不支持,或者你想装到上不去Google Play的Kinlde上),但你又想安装这个应用,怎么办呢?
Enjoy233
2019/03/05
8.7K0
如何从Google Play下载Android应用的APK安装文件?
Google Drive 的信息检索
对于使用 Google 全家桶的公司,Google 文档类的信息泄露时常发生。出现这种情况主要的原因是文档的权限设置问题,用户可能将文档配置为 anyoneCanFind, anyoneWithLink, domainCanFind, domainWithLink,这四种权限都属于比较公开的权限。后两个属于在域内可以查看到文档,一般来说也是不提倡如此设置,尤其是文档中包含敏感信息的。
madneal
2023/09/21
2500
Google Drive 的信息检索
使用IDM从Google 云端硬盘链接上下载超大文件
6.当下载不动时(传输速度为0),点击暂停键,然后重新进行第2步,通过该操作获取下载链接,之后取消刚刚新下载的这个任务,然后替换掉当前下载不动的文件的地址,最后再点击开始即可。由于IDM支持断点续传,所以它会接着刚才的进度继续下载。
_DIY
2023/02/26
4.6K0
使用IDM从Google 云端硬盘链接上下载超大文件
Google Drive网盘挂载
​ GoIndex是一款部署在Cloudflare Workers的Google Drive目录索引程序,本篇介绍如何借助GoIndex+Cloudflare挂载Google Driver
hahah
2022/08/30
4.2K0
一个方便转存 Google Drive 分享文件的方法
用过 Google Drive (以下简称GD) 的朋友们应该都清楚,GD 分享的文件可以一键添加到自己的云盘中,速度很快,一度让我感觉 Google 好牛,但仔细一看会发现这并不是将文件转存到自己的 GD 中,以大神分享的爱情公寓5资源为例:
宋天伦
2020/07/16
11.1K0
一个方便转存 Google Drive 分享文件的方法
Colaboratory配合Google Drive使用GPU运行机器学习代码
由于每次打开文件后台资源都是随机分配的,在运行代码之后一定要记得将结果保存。当然有的时候我们可以直接将所需文件上传到google drive上,由于资源随机分配,因此需要建立他们之间的关系。以下操作每次打开的时候,也需要重新执行。
听城
2018/10/09
1.7K0
Colaboratory配合Google Drive使用GPU运行机器学习代码
JupyterLab 与 Google Drive的完美融合!
说到云存储选项,有太多的选项可供选择:Google Drive、OneDrive和Dropbox适用于普通用户,如果你想要更安全的服务,Tresorit 或 PCloud 也可以选择。但你可能对这些都不太感兴趣,主要原因是我们想知道我的数据在哪里,而“在某个遥远的地方”并不能让我们很满意。这就是我们更热衷于家庭云解决方案的原因。
量化投资与机器学习微信公众号
2020/02/14
3.4K0
将 WebUI Colab 安装到 Google Drive
将 WebUI Colab 安装到 Google Drive Colab 页面功能 一次性安装和更新 跑步 添加模型 教程 稳定的扩散 WebUI Colab 与 Google Drive:ht
西里国际站
2023/08/23
4251
将 WebUI Colab 安装到 Google Drive
2021 年Google Drive 占云存储站点恶意软件下载量最多
网络犯罪分子越能利用合法服务,他们就越有可能诱骗人们上当受骗。这就是为什么谷歌和微软等流行服务被用于恶意攻击的原因。事实上,据安全提供商 Netskope 称,截至 2021 年,Google Drive 成为恶意软件下载滥用最多的云存储服务。
Khan安全团队
2022/01/12
1K0
GDocs for Google Drive Mac(谷歌云端辅助软件)
需要一款谷歌云端辅助软件?GDocs for Google Docs是完美的 Google Drive 伴侣,它功能非常齐全,可让您轻松创建、查看、共享、下载、导出您的文档,从任何地方使用共享菜单在 GDocs for Google Docs 中打开 Google Docs 链接,不会再迷失在您的网络浏览器选项卡中,需要的朋友快来下载体验吧!
快乐的小丸子
2022/09/18
1.3K0
GDocs for Google Drive Mac(谷歌云端辅助软件)
GDocs for Google Drive Mac(谷歌云端辅助软件)
GDocs for Google Docs是完美的 Google Drive 伴侣,它功能非常齐全,可让您轻松创建、查看、共享、下载、导出您的文档,从任何地方使用共享菜单在 GDocs for Google Docs 中打开 Google Docs 链接,不会再迷失在您的网络浏览器选项卡中。
Mac知识分享
2022/09/16
1K0
linux使用curl命令_如何使用curl从Linux命令行下载文件
The Linux curl command can do a whole lot more than download files. Find out what curl is capable of, and when you should use it instead of wget.
用户7886150
2020/12/30
4.6K0
实战 HomeAssistant 基于 Google Drive Backup 进行备份
今天给大家介绍的是 HA 的备份,虽然官方自带有备份功能,但仅能备份至本地存储,要想备份至云端就需要使用第三方加载项了
远哥制造
2023/09/25
1.5K0
如何从YouTube下载中文/英文双语字幕文件
有时候我们需要从YouTube上面下载英文视频,但是如果只有视频,而没有字幕的话,很难看懂视频内容。因此一般我们需要把英文字幕和中文字幕两种一起下载下来,这样方便学习和观看。那么如何从YouTube上面下载中文和英文双语字幕呢?可以试试Gihosoft TubeGet软件,各种语言的字幕都可以保存下载,如果有需要的话,也可以将字幕和视频合并成一个文件,非常的方便。下面我们一起来看下操作方法。
红豆沙
2020/10/20
7.3K0
如何从YouTube下载中文/英文双语字幕文件

相似问题

在SD卡上安装Linux有什么问题吗?

10

我的Arch Linux上的konqueror有什么问题?

10

在GRUB上安装Kali Linux有困难

10

Arch Linux :在Linux中RPi上的时间有多精确?

10

在Linux上启动进程的方法有哪些?

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文