使用 Mockito 进行 Retrofit 2 api 调用的单元测试

2023-11-22

我需要一些关于如何模拟 Rest api 的建议。我的应用程序采用 MVP 架构。

我的API接口:

public interface MyAPI {

    @GET("{cmd}/{userName}/{password}")
    Observable<Response> login(
        @Path("cmd") String cmd,
        @Path("userName") String userName,
        @Path("password") String password
    );

我的服务:

public class MyService implements IService {

    private static MyService mInstance = new MyService();
    private MyAPI mApi;

    public static MyService getInstance() {
        return mInstance;
    }

    private MyService() {

        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        httpClientBuilder.connectTimeout(Config.DEFAULT_TIMEOUT, TimeUnit.SECONDS);

        Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(Config.kBaseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(httpClientBuilder.build())
            .build();

        this.mApi = retrofit.create(MyAPI.class);
    }

    public void login(
        Subscriber<Response> subscriber,
        String userName,
        String password) {
        mApi.login(Config.kLoginCmd,userName,password)
            .subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(subscriber);
    }

我的演讲者班级:

public class LoginPresenter implements LoginContract.Presenter {

    LoginContract.View mView;
    IService mService;
    ISession mSession;

    public LoginPresenter(LoginContract.View loginView, IService service, ISession session) {
        mView = loginView;
        mService = service;
        mSession = session;
    }

    @Override
    public void login(String email, String password) {

        Subscriber<Response> subscriber = new Subscriber<Response>() {
            @Override
            public void onCompleted() {
                mView.showLoading(false);
            }

            @Override
            public void onError(Throwable e) {
                mView.showError(e.getLocalizedMessage());
            }

            @Override
            public void onNext(Response response) {
                if (response.getResults().getStatus().equalsIgnoreCase(Config.kResultCodeOK)) {
                    mView.loginSuccess();
                } else {
                    mView.showError(response.getResults().getStatus().getErrmsg());
                }
            }
        };

        mView.showLoading(true);
        mService.login(
            subscriber,
            email,
            password);
    }

还有另一种方法可以通过编写模拟服务来测试我的演示者。但我不太喜欢这样,我认为 Mockito 可以提供帮助。

这是我的测试课:

public class LoginPresenterMockTest {

    private LoginPresenter mLoginPresenter;

    @Mock
    LoginContract.View view;
    @Mock
    IService service;
    @Mock
    ISession session;

    @Before
    public void setup() throws Exception {
        MockitoAnnotations.initMocks(this);
        mLoginPresenter = new LoginPresenter(view, service, session);
    }

    @Test
    public void testLoginWithCorrectUserNameAndPassword() throws Exception {
        mLoginPresenter.login("[email protected]","password");
        verify(view).loginSuccess();
    }

}

我想做的是当响应正确时模拟响应数据调用 loginSuccess() 。

当然我现在的测试是行不通的。我需要一些关于如何嘲笑这个的建议?任何想法?谢谢。


您可以通过以下方式做到这一点:

@Test
public void testLoginWithCorrectUserNameAndPassword() throws Exception {
    // create or mock response object
    when(service.login(anyString(), anyString(), anyString).thenReturn(Observable.just(response));
    mLoginPresenter.login("[email protected]","password");
    verify(view).loginSuccess();
}

@Test
public void testLoginWithIncorrectUserNameAndPassword() throws Exception {
    // create or mock response object
    when(service.login(anyString(), anyString(), anyString).thenReturn(Observable.<Response>error(new IOException()));
    mLoginPresenter.login("[email protected]","password");
    verify(view).showError(anyString);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Mockito 进行 Retrofit 2 api 调用的单元测试 的相关文章

  • Android 应用程序安装失败:包 com.my.app 在条目 AndroidManifest.xml 处没有证书

    在 Android Studio 中 我生成了带有密钥库等的签名 APK 将 APK 安装到设备上时失败 并显示 无法安装应用程序 并且在 Android Monitor 中我看到以下行 Package com my app has no
  • Android:初始化本机 AudioRecord 对象时 AudioRecord 错误代码 -20

    Android 我想从麦克风读取缓冲区 以便我可以对其执行处理 以下是我的代码 int sampleRateInHz 8000 44100 22050 and 11025 int channelConfig AudioFormat CHAN
  • 在 ChromeO 上安装未知来源的 apk

    我今天早上更新了我的 Chromebook Asus Flip 以获取 Play 商店 我的 Chromebook 安装了 M53dev 通道版本 它运作良好 我可以安装并运行从 Play 商店下载的 Android 应用程序 我想测试我的
  • 拖动时跳转 ImageView。 getX() 和 getY() 值正在跳跃

    我创建了一个用于拖动视图的 onTouchListener 如果我使用的话 图像可以顺利拖动getRawX and getRawY 问题是 当您向下放置第二个指针然后抬起第一个指针时 图像将跳转到第二个指针 此 onTouchListene
  • 带有 Android 支持库 v7 的 Maven Android 插件

    我使用 maven android plugin 构建我的 android 应用程序 它依赖于 android 支持库 v4 和 v7 由于我没有找到如何从developer android com下载整个sdk 因此我无法使用maven
  • 覆盖 Android 中的电源按钮

    我正在开发一个应用程序 其中我需要在按下电源按钮时执行一个操作 但不幸的是我无法处理按下电源按钮时的操作 我尝试使用 onKeyDown 和dispatchKeyEvent 方法 但似乎没有任何效果 任何人都可以建议我解决这个问题的任何其他
  • Fragment 问题中的 ExpandableListView

    我正在尝试在片段中实现可扩展列表视图 没有错误出现 当我尝试记录两个的输出时List
  • Android 全屏对话框确认和拒绝操作

    材料设计中的全屏对话框应该在操作栏 工具栏上有确认和拒绝操作 我的问题是 我该怎么做 显示对话框 getFragmentManager beginTransaction add R id container new MyDialogFrag
  • 从ListView中隐藏行而不占用空间

    我有一个带有关联 ArrayAdapter 的 ListView 它在多个活动中显示其内容 不幸的是 现在有必要 我的 ListView 在其中一项设置中不显示其所有元素 而仅显示 属性 未设置为 true 的元素 我想避免使用两个具有不同
  • 如何禁用操作栏上“向上”按钮的翻转?

    背景 我做了一个 应用程序管理器 https play google com store apps details id com lb app manager 替代应用程序 我希望添加 RTL 从右到左 语言的翻译 因为我知道在某些 And
  • React Native Expo StackNavigator 重叠通知栏

    我正在尝试为我的 React Native Expo 应用程序实现导航栏 这里有一个问题 dependencies expo 18 0 3 react 16 0 0 alpha 12 react native 0 45 1 react na
  • 在新的 intel x86 android 模拟器中访问 google api

    我只是尝试在新的 x86 android 模拟器中运行我公司的应用程序 但是我们的应用程序依赖于 google 地图 API 而这在 google 随 android sdk 版本 17 提供的 x86 系统映像中不可用 我的直觉告诉我答案
  • Android蓝牙java.io.IOException:bt套接字已关闭,读取返回:-1

    我正在尝试编写一个代码 仅连接到运行 Android 5 0 KitKat 的设备上的 目前 唯一配对的设备 无论我尝试了多少方法 我仍然会收到此错误 这是我尝试过的最后一个代码 它似乎完成了我看到人们报告为成功的所有事情 有人能指出我做错
  • Android 上的 MIDI:Java 和/或 AIR 库

    一段时间以来 我一直在考虑在 iPad 上 重新 构建一个应用程序 其中我将使用 Objective C 和DSMI http dsmi tobw net 将 MIDI 信号发送到主机 这还不错 我的意思是 除了实际编写应用程序之外 现在我
  • 如何将 Android 添加到 Phonegap 平台版本 3

    经过大量挖掘 我相信这个问题 https stackoverflow com questions 18423444 phonegap 3 doesnt work with andriod studio与我没有添加任何用于构建phonegap
  • 如何为我的 Android Market APK 创建证书?

    我想将我的第一个 APK 应用程序上传到 Android Market 但我收到了此错误 顺便说一下 在 stackoverflow 中搜索时并没有引导我找到正确的链接 市场不接受使用调试证书签名的 APK 创建有效期至少 50 年的新证书
  • 在复杂的文件夹结构中进行测试

    我正在 golang 中构建一个设计模式存储库 为了运行所有测试 我使用这个 bash 脚本 有用 bin bash go test creational abstract factory go go test creational bui
  • Android 标记如何实现拖放?

    你好 我正在 Android 中开发 MapView 应用程序 我有三个标记 我希望稍后能够使用 Google Map API getlocation function 为了尝试一下 我想使用拖放功能移动标记 然后检查位置 任何人都可以通过
  • LifeCycleAware Fragment 中的片段生命周期事件

    我有一个生命周期感知片段和一个LifecycleObserver class public class MyFragment extends Fragment Override public void onCreate Nullable B
  • 如何访问我的 Android 程序中的联系人

    我正在制作一个短信应用程序 并且想要访问我的 Android 应用程序中的联系人 我想访问联系人 就像他们在实际联系人列表中一样 选择后 我需要返回到我的活动 在其中我可以向该人发送短信 或者是否可以访问存储联系人的数据库 我的代码如下所示

随机推荐

  • 如何从子例程中不返回任何内容?

    我想在执行下一步之前验证一个条件 但只发出警告并跳过当前值而不是死掉 如何重写 validate me 子例程而不返回任何值 Update 请注意 以下代码按预期工作 只是我想要其他东西 而不是从 validate me 返回 1 或 0
  • 保存图像,然后在 Swift (iOS) 中加载它

    我正在使用 saveImage 保存图像 func saveImage image UIImage path String gt Bool let pngImageData UIImagePNGRepresentation image le
  • d3.js 构建矩形网格

    我正在尝试在 d3 js 中构建一个矩形网格 网格有 7 行 一周中的几天 和 24 列 一天中的小时 以下代码仅绘制 行 列 天0 小时0 第 1 天 1 小时 第 2 天 第 2 小时 第 3 天 第 3 小时 第 4 天 第 4 小时
  • R 分组显示所有因子水平的计数,即使 dplyr 为零

    set seed 1 dat lt data frame ID sample letters 50 rep TRUE dat gt group by ID gt summarise no rows length ID 我有上面的代码 它创建
  • 了解 Java 内存模型和垃圾收集 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我经常会收到很多学生或寻找
  • 从 GCE VM 分离启动磁盘

    我正在尝试从 GCE 虚拟机分离启动磁盘 由于虚拟机已停止 因此它应该允许我将其分离 但它返回此错误 UNSUPPORTED OPERATION Hot remove of the root disk is not supported 有什
  • 如何只加载最后一个分区的数据

    我有一些数据是这样分区的 data year 2016 month 9 version 0 data year 2016 month 10 version 0 data year 2016 month 10 version 1 data y
  • 以编程方式实例化 Sharepoint 中的 Web 部件页面

    是否有一种简单的方法可以使用对象模型或 Web 服务以编程方式将 Web 部件页面添加到 Sharepoint 站点 以这种方式创建列表和添加 Web 部件似乎很简单 但我找不到如何创建内容页面的示例 编辑 对于普通的 WSS 安装 不是
  • Java 中的加权线性回归

    有谁知道 Java 中的科学 数学库可以直接实现加权线性回归吗 类似于接受 3 个参数并返回相应系数的函数 linearRegression x y weights 这看起来相当简单 所以我想它存在于某个地方 PS 我尝试过弗兰尼根的图书馆
  • 将 12 小时日期/时间转换为 24 小时日期/时间

    我有一个制表符分隔文件 其中每条记录都有一个 12 小时格式的时间戳字段 月 日 年 时 分 秒 AM PM 我需要快速将这些字段转换为 24 小时时间 月 日 年 HH mm ss 最好的方法是什么 我在 Windows 平台上运行 但除
  • 既然延迟已从反应导航中删除,如何“延迟加载”选项卡导航器屏幕

    React navigation 的维护者已从库中删除了 lazy true 导致所有选项卡尝试立即渲染 并获取先前由 lazy 控制的内容 现在乱序触发 为了保持类似的功能 如何强制在选项卡屏幕上等待 以便在第一次获得焦点之前不加载或调用
  • 如何使用 ITranscriptLogger 和 TranscriptLoggerMiddleware 在 cosmos DB 中存储聊天记录

    我想使用 ITranscriptLogger 和 TranscriptMiddelWare 将整个聊天历史记录存储在 cosmos DB 中 但我很难做到这一点 我读过了这篇 MS 文章 但我想将其存储在 Cosmos DB 中而不是 Bl
  • 有兴趣制作一个 PHP 脚本,将 IP 地址从定义的起始地址递增到定义的结束地址

    我知道我可以通过首先使用 PHP 内置函数将 IP 地址转换为十进制表示法来轻松做到这一点up2long and long2ip 我只是希望能够使用标准 IP 地址表示法做同样的事情作为练习 我想的问题是这样的 给定一个起始IP地址 比如1
  • 可以不使用括号调用单参数Python函数吗? [复制]

    这个问题在这里已经有答案了 Python 文档指定 如果函数仅采用单个参数 则省略括号是合法的 但是 myfunction Hello 产生语法错误 那么 到底是怎么回事呢 EDIT 我读到的声明仅适用于生成器表达式 在只有一个参数的调用中
  • grep 自动忽略文件

    有什么方法可以使用 grep 在搜索某些内容时忽略某些文件 相当于 svnignore 或 gitignore 吗 我在搜索源代码时通常使用类似的东西 grep r something grep v ignore file1 grep v
  • 与 QLabel 和 QLineEdit 中的右侧文本对齐

    我有一个QLabel就在下面一个QLineEdit具有相同的尺寸和对齐属性 QLineEdit lineEdit new QLineEdit 999 lineEdit gt setFixedWidth 100 lineEdit gt set
  • jni 调用以自定义 java 接口作为参数的 java 方法

    我正在cocos2d x平台上开发一个插件项目 我想编写一些c 包装器接口来通过调用java方法JNI from jar软件开发工具包 我知道如何使用 JNI 调用静态 java 方法 但我对 java 函数中的接口参数感到困惑 我有一个处
  • 重复字符在 PowerShell 中不起作用

    我想在 PowerShell 中重复一个字符 例如 test this is a test that I want to underline with Write Host test Write Host test length 然而 上述
  • npm 以一种奇怪的递归方式安装依赖项

    I used npm install dev安装a中列出的依赖项package json文件 似乎不是以平面结构安装所有包 而是在模块目录中安装每个模块的依赖项 我不得不取消它 因为它花了很多时间 因为许多依赖项应该已经得到满足 但它必须在
  • 使用 Mockito 进行 Retrofit 2 api 调用的单元测试

    我需要一些关于如何模拟 Rest api 的建议 我的应用程序采用 MVP 架构 我的API接口 public interface MyAPI GET cmd userName password Observable