自定义 Shadow 对象在 Robolectric 中到底是如何工作的?
如果我为我的 Activity 编写一个自定义 Shadow,并将其注册到 RobolectricTestRunner,那么框架是否会在 Activity 启动时用我的自定义 Shadow 拦截该 Activity?
谢谢。
If I write a custom Shadow for my Activity, and registering it with RobolectricTestRunner, will the framework intercept the Activity with my custom Shadow whenever it's started?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
简短的回答是否定的。
Robolectric 对拦截和检测的类别有选择性。在撰写本文时,要检测的唯一类必须具有与以下选择器之一匹配的完全限定类名:
Robolectric 存在的全部原因是 Android SDK jar 中提供的类在 JVM 中调用时会抛出异常(即不在模拟器或设备上)。您的应用程序的 Activity 具有非“敌对”源(调用方法或构造函数时它可能不会引发异常)。 Robolectric 的预期目的是允许您测试应用程序的代码,否则由于 SDK 的编写方式而无法实现这一点。创建 Robolectric 的其他一些原因是:
显然可以更改代码来隐藏任何类。过去有人讨论过将阴影功能提取到独立库中,以帮助使用其他一些对测试不利的 API 编写测试。
为什么要跟踪您的 Activity?
The short answer is no.
Robolectric is selective about what classes it intercepts and instruments. At the time of this writing, the only classes that will be instrumented must have a fully qualified classname match one of these selectors:
The whole reason for Robolectric's existence is that the classes provided in the Android SDK jar throw exceptions when invoked in a JVM (i.e. not on an emulator or device). Your application's Activity has source that is not 'hostile' (it probably does not throw exceptions when the methods or constructors are invoked). Robolectric's intended purpose is to allow you to put your application's code under test, which would otherwise not be possible due to the way the SDK is written. Some of the other reasons why Robolectric was created were:
The code could clearly be changed to shadow any class. There has been talk in the past about extracting the shadowing features into a standalone library, to assist writing tests using some other test-hostile api.
Why do you want to shadow your Activity?
Robolectric 2 对此有了显着的改变。您可以在配置中指定自定义阴影,而不是编写自己的阴影测试运行者。
例如:
This has significantly changed with Robolectric 2. You can specify custom shadows in the configuration instead of writing your own TestRunner.
For example:
是的,如果您对 RobolectricTestRunner 进行子类化,请向构造函数添加自定义包并在 bindShadowClasses 方法中加载 Shadow 类。无需使用 android.* 包技巧。
(注意:这是在 robolectric-1.1 中)
RobolectricTestRunner#setupApplicationState 中提供了许多可以覆盖的钩子。
这是我对 RobolectricTestRunner 的实现。
您可以继承更多
方法(来自 RobolectricTestRunner.class),
这是在 Robolectric TestRunner 中调用它们的位置:
Yes, if you subclass the RobolectricTestRunner, add a custom package to the constructor and load your Shadow classes in the bindShadowClasses method. No need to use the android.* package trick.
(Note: this is with robolectric-1.1)
There are a number of hooks provided in the RobolectricTestRunner#setupApplicationState that you can override.
Here's my implementation of the RobolectricTestRunner.
}
More methods you can subclass (from RobolectricTestRunner.class)
Here's where they're called in the Robolectric TestRunner:
作为更新,我已经能够创建自己的类的影子,只要在任何可能的加载程序作用于该类之前小心绑定影子类即可。因此,根据说明,我在 RoboRunner 中做了:
我是否提到过我有点作弊?上面的原始答案(当然)是正确的。所以我将其用于我的真实课程:
正如人们所期望的那样,我的模拟(影子)位于我的测试包后面:
As an update, I have been able to create shadows of my own classes, as long as am careful to bind the shadow class before any possible loader acts on that class. So, per the instructions, in the RoboRunner I did:
Did I mention that I'm cheating a bit? The original answer above is (of course) correct. So I use this for my real class:
And my mock (shadow) is in back in my test package, as one might expect:
可能会迟到,但从这里:org.robolectric.bytecode.Setup,您可能会找到有关检测哪些类的更多详细信息。
Might be late, but from here: org.robolectric.bytecode.Setup, you might find further detail about what classes are instrumented.