Extending Robolectric
Robolectric is a work in progress, and we welcome contributions from the community. We encourage developers to use the standard GitHub workflow to fork, enhance, and submit pull requests to us.
Shadow Classes
Robolectric defines many shadow classes, which modify or extend the behavior of classes in the Android OS. When an Android class is instantiated, Robolectric looks for a corresponding shadow class, and if it finds one it creates a shadow object to associate with it. Every time a method is invoked on an Android class, Robolectric ensures that the shadow class' corresponding method is invoked first (if there is one), so it has a chance to work its magic. This applies to all methods, even static and final methods, because Robolectric is extra tricky!
//robolectric定义了很多影子类,这些类修改或者继承了Android操作系统中类的行为,当一个android类被初始化了,robolectric寻找一个对应的影子类,而且如果它找到了他就会创建一个与它关联的影子对象。每次一个方法被Android类调用,rebolectric都会确保影子类对应的方法会首先被调用(如果有这个对应的方法),影子应用到了所有的方法,深知静态和final方法。因为robolectrix很牛逼。
What's in a Name?
Why "Shadow?" Shadow objects are not quite Proxies, not quite Fakes, not quite Mocks or Stubs. Shadows are sometimes hidden, sometimes seen, and can lead you to the real object. At least we didn't call them "sheep", which we were considering.
//反正就是和之前的原生的功能不是很一样。这个名字已经很不错了,和我们之前考虑过的“胆小鬼”相比。
Adding Functionality
If the shadow classes provided with Robolectric don't do what you want, it's possible to change their behavior for a single test, a group of tests, or for your whole suite. Simply declare a class (let's say ShadowFoo) and annotate it @Implements(Foo.class). Your shadow class may extend one of the stock Robolectric shadows if you like. To let Robolectric know about your shadow, annotate your test method or class with the @Config(shadows=ShadowFoo.class), or create a file calledorg.robolectric.Config.properties containing the line shadows=my.package.ShadowFoo.
//如果影子类提供的没有你想要的,对于某一个测试,或者一些测试,或者全部的测试类做一些修改是必要的。只需要声明一个类然后注释它@Implements。为了让robolectric知道你的影子,使用 @Config(shadows=ShadowFoo.class)注释你的测试方法或者类
From Robolectric 2.0 on, the number of shadow classes needed is greatly reduced, because real Android OS code is present. Methods on your shadow class are able to call through to the Android OS code if you like, using Robolectric.directlyOn().
Shadow Classes
Shadow classes always need a public no-arg constructor so that the Robolectric framework can instantiate them. They are associated to the class that they Shadow with an @Implements annotation on the class declaration. In general, they should be implemented as if from scratch, the facilities of the classes they Shadow have almost always been removed and their data members are difficult to access. The methods on a Shadow class usually either Shadow the methods on the original class or facilitate testing by setting up return values or providing access to internal state or logged method calls.
//shadow类总是需要一个公有的午餐构造方法以便让robo框架可以初始化。他们会和使用 @Implements 声明的类关联起来作为它们的影子。影子类中的方法要么是对原来类中方法的重复,要么修改了返回值或者提供的全局变量的访问或者记录方法调用轨迹。
Shadow classes should mimic the production classes' inheritance hierarchy. For example, if you are implementing a Shadow forViewGroup, ShadowViewGroup, then your Shadow class should extend ViewGroup's superclass's Shadow, ShadowView.
//影子类应该同样照搬原类的继承关系。
...
@Implements(ViewGroup.class)
public class ShadowViewGroup extends ShadowView {
...
Methods
Shadow objects implement methods that have the same signature as the Android class. Robolectric will invoke the method on a Shadow object when a method with the same signature on the Android object is invoked.
Suppose an application defined the following line of code:java ... this.imageView.setImageResource(R.drawable.pivotallabs_logo); ...
Under test the ShadowImageView#setImageResource(int resId) method on the Shadow instance would be invoked.
//假设应用中定义了一行代码 this.imageView.setImageResource(R.drawable.pivotallabs_logo);,那在测试下影子类的实例的对应影子方法也会被调用
Shadow methods must be marked with the @Implementation annotation. Robolectric includes a lint test to help ensure this is done correctly.
//影子方法必须使用 @Implementation注释标记。
@Implements(ImageView.class)
public class ShadowImageView extends ShadowView {
...
@Implementation
public void setImageResource(int resId) {
// implementation here.
}
}
It is important Shadow methods are implemented on the corresponding Shadow of the class in which they were originally defined. Otherwise Robolectric's lookup mechanism will not find them (even if they have been declared on a Shadow subclass.) For example, the method setEnabled() is defined on View. If a setEnabled() method is defined on ShadowViewGroup instead of ShadowViewthen it will not be found at run time even when setEnabled() is called on an instance of ViewGroup.
//shadow方法只会实现对应原类的方法,子类的实现在这个逻辑里无效不可继承
Shadowing Constructors
Once a Shadow object is instantiated, Robolectric will look for a method named __constructor__ which has the same arguments as the constructor that was invoked on the real object.
//一旦shadow对象被初始化,robo将会寻找和真实对象中被调用的参数一样的,名字为 __constructor__的方法调用。
For instance, if the application code were to invoke the TextView constructor which receives a Context:
new TextView(context);
Robolectric would invoke the following __constructor__ method that receives a Context:
@Implements(TextView.class)
public class ShadowTextView {
...
public void __constructor__(Context context) {
this.context = context;
}
...
Getting access to the real instance
Sometimes Shadow classes may want to refer to the object they are shadowing, e.g. to manipulate fields. A Shadow class can accomplish this by declaring a field annotated @RealObject:
//有时候shadow类可能想要引用他们shadow的对象,例如,去操作变量。一个shadow类可以通过声明@RealObject注解的对象来实现
@Implements(Point.class)
public class ShadowPoint {
@RealObject private Point realPoint;
...
public void __constructor__(int x, int y) {
realPoint.x = x;
realPoint.y = y;
}
}
Robolectric will set realPoint to the actual instance of Point before invoking any other methods.
It is important to note that methods called on the real object will still be intercepted and redirected by Robolectric. This does not often matter in test code, but it has important implications for Shadow class implementors. Since the Shadow class inheritance hierarchy does not always mirror that of their associated Android classes, it is sometimes necessary to make calls through these real objects so that the Robolectric runtime will have the opportunity to route them to the correct Shadow class based on the actual class of the object. Otherwise methods on Shadows of base classes would be unable to access methods on the Shadows of their subclasses.
Extending Robolectric的更多相关文章
- Robolectric
今天学习了单元测试框架,Robolectric.初步感觉,可能我测试的少,没有感觉Robolectric能有多大的帮助.虽然可以帮助创建activity.可以模拟点击事件.可是有什么呢. 好吧,讲下使 ...
- Android 单元测试(junit、mockito、robolectric)
1.运用JUnit4 进行单元测试 首先在工程的 src 文件夹内创建 test 和 test/java 文件夹. 打开工程的 build.gradle(Module:app)文件,添加JUnit4依 ...
- Android studio下gradle Robolectric单元测试配置
android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供 ...
- Robolectric 配置
费了些工夫,已配好,按记录留记录 按官网操作http://robolectric.org/getting-started/ 1引包 testCompile "org.robolectric: ...
- Embeding Python & Extending Python with FFPython
Introduction ffpython is a C++ lib, which is to simplify tasks that embed Python and extend Python. ...
- 在Android Studio中用Gradle添加Robolectric
我们用Robolectric测试的话需要在gradle中进行配置,国内的详细教程太过简易,而且很多是低版本下的配置方案.所以经过本人的仔细摸索,找到了现在高版本中的配置方案,主要还是参考了官网的配置教 ...
- (转) Written Memories: Understanding, Deriving and Extending the LSTM
R2RT Written Memories: Understanding, Deriving and Extending the LSTM Tue 26 July 2016 When I was ...
- robolectric环境的搭建
最近在学习测试驱动开发(Test-Driven Development),测试驱动开始是极限编程的一种方式,提倡在真正编写代码之前先根据需求编写测试代码(当然这个测试代码是不可能通过的),然后根据测试 ...
- Extending JavaScript Natives
Most built-in JavaScript types are constructors whose prototypes contain the methods and other prope ...
随机推荐
- [CF Round #294 div2] E. A and B and Lecture Rooms 【树上倍增】
题目链接:E. A and B and Lecture Rooms 题目大意 给定一颗节点数10^5的树,有10^5个询问,每次询问树上到xi, yi这两个点距离相等的点有多少个. 题目分析 若 x= ...
- Ireport 报表导出 Poi + ireport 导出pdf, word ,excel ,htm
Ireport 报表导出 Poi + ireport 导出pdf, doc ,excel ,html 格式 下面是报表导出工具类reportExportUtils 需要导出以上格式的报表 只需要调用本 ...
- [spring-framework]Spring定时器的配置和使用
开发中我们常常会做一些定时任务,这些任务有开始时间,并会按一定的周期或规则执行.如此我们在Java程序开发中使用定时器来处理定时任务. <!-- MessageRequestTask类中包含了m ...
- SSH自定义标签
一.标签处理类:package cn.conris.sys.form; import java.io.IOException; import java.util.Enumeration; impor ...
- java 中的访问修饰符
一. public:所有类都可以访问 protected:所有子类和同包下的类都可以访问 缺省:同包类都可以访问 private:类本身才可以访问 注意点:protected修饰类属性时,例如 pac ...
- 在ubuntu14.04 64位中使用jd-gui
使用时提示缺少库,输入命令sudo apt-get install libgtk2.0-0:i386 libxxf86vm1:i386 libsm6:i386 lib32stdc++6 参考:http ...
- 有关DOM的小总结
一直以为DOM(文档对象模型)是JS中最简单的一部分.不可否认,它确实很简单,因为DOM的思维模式有点固定,只需要简单地记住一些固定的方法,所以DOM可以说是所有js(这里指的是客户端的js)入门的起 ...
- vijosP1014 旅行商简化版
vijosP1014 旅行商简化版 链接:https://vijos.org/p/1014 [思路] 双线DP. 设ab,ab同时走.用d[i][j]表示ab所处结点i.j,且定义i>j,则有转 ...
- [待解决问题] 启动不了Android工程
在使用 AudioInputStream sample = AudioSystem.getAudioInputStream(voiceSampleFile); 调用javax.sound.sample ...
- 《A First Course in Probability》-chaper8-极限定理-弱大数定理
基于之前强大数定理的得证,这里我们再结合切比雪夫不等式,能够得到弱大数定理. 弱大数定理: 表面上,强大数定理和弱大数定理好像是质同的,但是他们之间真正的区别到底是什么呢?