PowerMock + Robolectric + Dagger2。第一部分

2023-12-25


这个问题是从第一部分创建的PowerMock + Robolectric + Dagger2 https://stackoverflow.com/questions/34689722/powermock-robolectric-dagger2
所以我又有点了。对不起。

我测试自定义视图类,其中包含:

  1. 安卓用户界面元素
  2. 一些逻辑
  3. 静态方法调用
  4. dagger2 依赖项


所以我使用下一个工具进行测试

  1. 用于 UI 元素模拟的 Robolectric
  2. 逻辑测试的单元测试
  3. 用于静态方法模拟的 PowerMock

Robolectric + PowerMock 集成问题已知且解决方案已知 -https://github.com/robolectric/robolectric/wiki/Using-PowerMock https://github.com/robolectric/robolectric/wiki/Using-PowerMock
但使用此解决方案 dagger2 依赖项会失败。

注意代码
我的自定义视图 -进度文本视图:

public class ProgressTextView extends TextView {

    private String defaultText;
    private int fileSize;
    private String fileSizeString;
    private FileDownloaderI fileDownloader;

    @Inject
    FileDownloaderManager fileDownloaderManager;

    Subscription downloadProgressChannelSubscription;
    Subscription downloadCancelChannelSubscription;

    public ProgressTextView(Context context) {
        super(context);
        provideDependency();
    }

    public ProgressTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        provideDependency();
    }

    public ProgressTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        provideDependency();
    }

    private void provideDependency() {
        ApplicationSIP.get().applicationComponent().inject(this);
    }

}

应用SIP:

public class ApplicationSIP extends Application {

    public static volatile Context applicationContext;

    @NonNull
    private AppComponent appComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        applicationContext = getApplicationContext();
        Logger.registerLogger(this);

        appComponent = prepareApplicationComponent().build();
        appComponent.inject(this);
    }

    @NonNull
    protected DaggerAppComponent.Builder prepareApplicationComponent() {
        return DaggerAppComponent.builder()
                .appModule(new AppModule(getApplicationContext()))
                .tGModule(new TGModule());
    }

    @NonNull
    public AppComponent applicationComponent() {
        return appComponent;
    }

    @NonNull
    public static ApplicationSIP get() {
        return (ApplicationSIP) applicationContext.getApplicationContext();
    }

}

应用组件:

@Component(modules = {AppModule.class, TGModule.class, MediaModule.class, StaticModule.class})
@Singleton
public interface AppComponent {   
    void inject(ApplicationSIP applicationSIP);
    void inject(ProgressDownloadView progressDownloadView);
    void inject(ProgressTextView progressTextView);
}

And 进度文本视图测试:

@RunWith(RobolectricUnitTestRunner.class)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Formatter.class)
public class ProgressTextViewTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();
    Activity activity;

    @Before
    public void beforeTest() {
        // PowerMockito
        PowerMockito.mockStatic(Formatter.class);
        Mockito.when(Formatter.formatFileSize(anyObject(), anyInt())).thenReturn("");
        // Robolectic
        activity = Robolectric.setupActivity(Activity.class);
    }

    @Test
    public void init_FileDownloaded() {
        ProgressTextView progressTextView = new ProgressTextView(activity);
        ...
    }
}

所以当我开始这个测试时,我得到下一个异常:

java.lang.NullPointerException
at com.tg.osip.ApplicationSIP.get(ApplicationSIP.java:64)
at com.tg.osip.ui.general.views.ProgressTextView.provideDependency(ProgressTextView.java:60)
at com.tg.osip.ui.general.views.ProgressTextView.<init>(ProgressTextView.java:46)
at com.tg.osip.ui.general.views.ProgressTextViewTest.init_FileDownloaded(ProgressTextViewTest.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:52)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1873)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:773)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:638)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401)
at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:98)
at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78)
at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

如果您更改机器人活动初始化放置:

@RunWith(RobolectricUnitTestRunner.class)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Formatter.class)
public class ProgressTextViewTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();
    Activity activity = Robolectric.setupActivity(Activity.class);

    @Before
    public void beforeTest() {
        // PowerMockito
        PowerMockito.mockStatic(Formatter.class);
        Mockito.when(Formatter.formatFileSize(anyObject(), anyInt())).thenReturn("");
    }

    @Test
    public void init_FileDownloaded() {
        ProgressTextView progressTextView = new ProgressTextView(activity);
        ...
    }
}

我得到其他异常:

java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:569)
at java.lang.StringBuffer.append(StringBuffer.java:369)
at java.io.StringWriter.write(StringWriter.java:94)
at com.thoughtworks.xstream.core.util.QuickWriter.flush(QuickWriter.java:73)
at com.thoughtworks.xstream.io.xml.PrettyPrintWriter.flush(PrettyPrintWriter.java:342)
at com.thoughtworks.xstream.XStream.toXML(XStream.java:858)
at com.thoughtworks.xstream.XStream.toXML(XStream.java:843)
at org.powermock.classloading.DeepCloner.clone(DeepCloner.java:53)
at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:89)
at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78)
at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:49)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188)
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

在回答你的问题之前。我会说:

  1. 你的观点是做/知道太多。我说的是知识FileDownloaderManager以及有关如何获取依赖项的知识
  2. 由于您使用的是注入,我会将静态函数包装到一个类中并注入它。编写/维护测试会更容易
  3. 甚至班级名称AppComponent说它不应该知道如何注入视图。考虑范围注入
  4. 部分未成年人患有applicationContext。为什么会这样volatile,您希望从非主线程访问它吗?已经是ApplicationSIP为什么需要使用应用程序上下文和转换?

终于等到答案了。第一个堆栈跟踪表明appContext一片空白。所以onCreate您的应用程序的未调用。我没有看到代码RobolectricUnitTestRunner但我认为问题出在使用电源模拟。第二个堆栈跟踪证明了这一点。所以我想说答案是停止使用电源模拟.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PowerMock + Robolectric + Dagger2。第一部分 的相关文章

  • android - EditText 打字速度很慢

    我的 EditText 在打字时响应速度很慢 这种滞后现象足以让我找到解决方案 我做了一些研究 发现了一个 SO 线程输入文本时 EditText 滞后 https stackoverflow com questions 6173591 a
  • 任务“:app:dexDebug”执行失败

    我目前正在处理我的项目 我决定将我的 Android Studio 更新到新版本 但在我导入项目后 它显示如下错误 Information Gradle tasks app assembleDebug app preBuild UP TO
  • 为什么 Kotlin 数据类可以在 Gson 的不可空字段中包含空值?

    在 Kotlin 中你可以创建一个data class data class CountriesResponse val count Int val countries List
  • 如何改变android中menuItem的背景颜色?

    我正在以编程方式将菜单项添加到菜单中 我想在选择特定项目时添加背景颜色 如何为 menuItem 添加背景 您的回答将不胜感激 虽然其他答案提供了更改样式 这会影响all菜单项 据我了解 需要更改一个菜单项 我建议你使用android ac
  • Android studio 在日志猫中“清除全部”,更改日志级别过滤器时日志仍然会回来

    在 LogCat 中 当我单击 全部清除 按钮时 它似乎清除了所有日志 但是 如果我更改日志级别并返回到之前的日志级别 则所有日志都会返回 例如 我正在查看 Verbose 我选择 全部清除 日志清除 我切换到 调试 我切换回 详细 现在所
  • 如何从另一个xml文件动态更新xml文件?

    我想从另一个 xml 文件更新 xml 文件 我使用了一个 xml 文件 如下所示 one xml
  • android 谷歌+登录定制

    我正在创建一个 Android 应用程序 现在我正在实现社交网络登录 Facebook 按钮很好 但 google 按钮的语言与 Facebook 不同 另外 它只说 登录 我想让它说 用谷歌登录 我是 android 编程的新手 看到我需
  • 在 Android 2.2 上运行 HelloCordova 时找不到类“android.webkit.WebResourceResponse”

    我尝试按照本教程进行操作 http docs phonegap com en 2 7 0 guide getting started android index md html Getting 20 Started 20with 20 An
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • OpenCV InRange 参数

    我在 Android 上使用 OpenCV 来实时查找特定颜色的圆圈 我的第一步是仅保留与我正在寻找的定义颜色相对应的像素 在本例中为红色或绿色 示例图像 https i stack imgur com CIozU jpg 为此 我正在使用
  • Android 在启动时启动服务,如何在设备重启后重新启动服务类?

    我需要在启动时启动一项服务 我搜索了很多 他们正在谈论广播接收器 由于我是 Android 开发新手 所以我对 Android 上的服务并没有清楚的了解 请提供一些源代码 您的接收者 public class MyReceiver exte
  • invalidateOptionsMenu 在片段中不起作用

    显示或隐藏项目ActionBar根据文本中是否有文本EditText or not 所以 我做了以下事情 public class NounSearch extends android app Fragment EditText seach
  • Python Kivy - 在本机网络浏览器中打开 url 的应用程序

    我尝试制作一个简单的应用程序 在单击 Screen One 上的按钮后 在 Kivy 中打开一个网页 我使用了这个主题 Python 在应用程序中直接显示网络浏览器 iframe https stackoverflow com questi
  • 在 Android 中使用 iText 读取或打开 PDF 文件

    我是 Android 应用程序开发新手 使用 iText 我完成了 PDF 创建并在创建的文件上写入 现在我想阅读该 PDF 文件 如何使用 iText 打开或阅读 PDF 文件 例子将是可观的 那么提前 哪个是渲染 PDF 文件的最佳库
  • 如何在android中录制音频时暂停背景音乐

    我正在 Android 中开发一个音频记录应用程序 因此 如果设备音乐播放器中已播放任何背景音乐 则应在开始录制之前暂停该背景音乐 并且每当录制停止或暂停时 背景音乐都应恢复 播放录制的音频时也应该如此 有人可以帮我解决这个问题吗 提前致谢
  • Google Android Drive api 在已安装版本上登录失败

    我开发了一个使用 GoogleDrive api 的 Android 应用程序 当处于调试状态或运行调试版本时 应用程序 工作正常 并正确验证附加的谷歌帐户 等 当我构建发行版本时 使用我的签名密钥 并且 安装apk文件 当我运行时 Goo
  • Spock模拟inputStream导致无限循环

    我有一个代码 gridFSFile inputStream bytes 当我尝试这样测试时 given def inputStream Mock InputStream def gridFSDBFile Mock GridFSDBFile
  • 按名称查找视图

    是否可以通过名称而不是 id 来查找视图 findViewById R id someView 但我想做这样的事情 findViewByName someView 在处理 xml 时 您必须通过标识符查找视图 但是您可以使用以下方式查找标识
  • Jetpack Compose 部分或开放侧边框

    我正在尝试绘制部分或一侧开放的矩形圆形边框以实现此效果 玩了一下之后我得到了这个 这是通过以下方式完成的 RoundedCornerShape topStartPercent 50 bottomStartPercent 50 start R
  • 绘制大位图时 nSyncAndDrawFrame 速度极慢

    我想用多个大位图优化视差滚动视图 在我的 Nexus 5 上 一切都很顺利 Traceview 转储如下所示 doFrame 方法大约需要 18 毫秒才能完成 但是 当使用我的 Nexus 7 或 Android 6 模拟器 Genymot

随机推荐

  • 如何将手动插入和JPA Id生成结合起来?

    我正在使用 arquillian 运行容器内测试 我通过添加一个来预填充数据库import sql到部署 在测试期间我想创建更多实体 不幸的是 这失败了PersistenceException javax persistence Persi
  • 如何在 Jetpack Compose Canvas 中绘制圆角多边形?

    我正在尝试使用创建一个圆角三角形Canvas在 Jetpack Compose 中 我尝试用这段代码来绘制三角形 Composable fun RoundedTriangle Canvas modifier Modifier size 50
  • Python 看门狗重复事件

    我创建了一个修改后的看门狗示例 以便监视已添加到 Windows 中特定目录的 jpg 照片文件 import time from watchdog observers import Observer from watchdog event
  • 如何从 Windows 设置环境变量

    在 windows xp 7 8 vista 10 等中添加环境变量的方法是什么 在 Windows 7 8 Vista 或 XP 中 在桌面或开始菜单中找到 我的电脑 图标 右键单击它 然后从菜单中选择 属性 项 当您看到属性对话框时 单
  • 在 Rails 中渲染 JSON 时包含关联模型

    现在我有这一行 render json programs except gt created at updated at 但是 由于程序属于公司 我想显示公司名称而不是公司 ID 渲染节目时如何包含公司名称 像这样的东西应该有效 rende
  • 如何通过 git pre-receive hook 验证用户身份

    我想写一个pre receivePython 中的 githook 据我了解 没有任何参数被传入pre receive脚本 而不是每个引用都是使用标准输入在单独的行上传递的 我已经能够通过以下方式阅读参考更改 usr bin env pyt
  • 如何创建具有静态返回类型的扩展方法?

    我试图编写一个简单的扩展方法Color返回该颜色的黑色和白色等效值的静态类 问题是扩展方法无法返回Static类型 那么 我该怎么做呢 请帮我 问题是没有方法可以返回静态类型 静态类是无状态的 或仅具有静态状态 因此只有一个 实例 可以从引
  • 对数据库中的所有表启用更改跟踪

    假设在 SQL Server 数据库上启用了更改跟踪 如何在数据库中的所有表上启用更改跟踪 您可以使用以下 T SQL 脚本生成另一个 T SQL 脚本 该脚本启用CHANGE TRACKING所有具有主键的表的功能 Step 1 Exec
  • 如何区分 jQuery 选择器字符串和其他字符串

    我想检查字符串的 类型 特别是 如何区分 jQuery 选择器字符串和其他字符串 也就是说 下面的代码中selectorTest应该如何实现呢 var stringType function value var htmlExpr lt lt
  • C++:#pragma comment(lib, "XXX") 实际上对“XXX”做什么?

    我的背景是 C 但我必须保留一些遗留的 MS C 在那个代码库中我偶然发现 pragma comment lib OtherLib700 lib 其中 700 是一些版本控制 除此之外 该库还有一个同名的 DLL 我首先认为该程序将依赖于
  • 如何从 OHLC 数据计算枢轴值

    我有一个带有 open high low close 和 key 列的 pandas 数据集 现在我想按键对数据集进行分组 并使用公式 最高价 最低价 收盘价 3 计算枢轴 到目前为止我可以做到 但要求是将计算的数据转移到下一组 我无法编码
  • pthread 中的信号处理

    我创建了一个 pthread 并在其中安装了一个信号处理程序 与我们在中所做的方式相同main 功能 线程的信号处理程序是一个单独的函数 令人惊讶的是 它不起作用 即线程的信号处理程序无法捕获信号 这是代码 include
  • NSNumberFormatterStyle.SpellOutStyle 中的错误?

    当我将 NSNumberFormatterStyle SpellOutStyle 用于较大的数字 不是溢出类型的数字 时 它似乎会在四万亿中的某个地方崩溃 let formatter NSNumberFormatter formatter
  • 为什么MySQL在违反唯一键约束时会出现自动增量间隙,但违反主键约束时却不会?

    我明白当使用INSERT ON DUPLICATE KEY UPDATE在 MySQL 中 当插入失败时 会出现自动增量间隙 然而 我注意到 只有在违反唯一键约束时才会出现间隙 如果主键约束失败 则不会出现自增间隙 两者差异的原因是什么 T
  • 当我尝试从表单 A 显示表单 B 时,为什么编译器会说“未声明的标识符”?

    为什么此代码不起作用 procedure TFormNotification Button3Click Sender TObject begin FormB Show end 我越来越未声明的标识符 error 您可能有一个名为的全局变量F
  • django {% if user.groups == 'FK' %} 不起作用[重复]

    这个问题在这里已经有答案了 我正在使用 django 制作一个网站 if user groups FC 在我的模板中不起作用 我有这样的组 For example one of my users username is hong belon
  • 如果查询中没有占位符/动态数据,您可以省略 PDO 准备吗?

    我目前正在开发一个将 PDO 与 MySQL 数据库结合使用的应用程序 我看到一些查询 它们非常简单SELECT声明 例如 SELECT FROM table ORDER BY name ASC 代码确实not use prepare 例如
  • 如何在 Protractor 中执行测试之前恢复数据库

    我在 Protractor 中编写了 E2E 测试 它使用节点通过 webdriver 运行 现在我有一些插入测试 它将插入数据并创建用户 现在 如果我第一次运行该案例 它将通过 但是当我重新运行测试时 它将失败 因为它已经存在 预期 当
  • Azure 可用性集和规模集的差异

    有人可以在 ARM 门户中定义两者之间的区别吗 另外 如果我需要将新的 Azure RM VM 添加到现有 AS 可用性集 PowerShell 会是什么 谢谢 普拉布 可用性集由一组离散的 VM 组成 这些 VM 具有自己的名称和各自的属
  • PowerMock + Robolectric + Dagger2。第一部分

    这个问题是从第一部分创建的PowerMock Robolectric Dagger2 https stackoverflow com questions 34689722 powermock robolectric dagger2 所以我又