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 forViewGroupShadowViewGroup, 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的更多相关文章

  1. Robolectric

    今天学习了单元测试框架,Robolectric.初步感觉,可能我测试的少,没有感觉Robolectric能有多大的帮助.虽然可以帮助创建activity.可以模拟点击事件.可是有什么呢. 好吧,讲下使 ...

  2. Android 单元测试(junit、mockito、robolectric)

    1.运用JUnit4 进行单元测试 首先在工程的 src 文件夹内创建 test 和 test/java 文件夹. 打开工程的 build.gradle(Module:app)文件,添加JUnit4依 ...

  3. Android studio下gradle Robolectric单元测试配置

    android studio下gradle Robolectric单元测试配置 1.Robolectric Robolectric是一个基于junit之上的单元测试框架.它并不依赖于Android提供 ...

  4. Robolectric 配置

    费了些工夫,已配好,按记录留记录 按官网操作http://robolectric.org/getting-started/ 1引包 testCompile "org.robolectric: ...

  5. Embeding Python & Extending Python with FFPython

    Introduction ffpython is a C++ lib, which is to simplify tasks that embed Python and extend Python. ...

  6. 在Android Studio中用Gradle添加Robolectric

    我们用Robolectric测试的话需要在gradle中进行配置,国内的详细教程太过简易,而且很多是低版本下的配置方案.所以经过本人的仔细摸索,找到了现在高版本中的配置方案,主要还是参考了官网的配置教 ...

  7. (转) Written Memories: Understanding, Deriving and Extending the LSTM

    R2RT   Written Memories: Understanding, Deriving and Extending the LSTM Tue 26 July 2016 When I was ...

  8. robolectric环境的搭建

    最近在学习测试驱动开发(Test-Driven Development),测试驱动开始是极限编程的一种方式,提倡在真正编写代码之前先根据需求编写测试代码(当然这个测试代码是不可能通过的),然后根据测试 ...

  9. Extending JavaScript Natives

    Most built-in JavaScript types are constructors whose prototypes contain the methods and other prope ...

随机推荐

  1. maven web项目不能创建src/main/java等文件夹的问题

    eclipse创建maevn web项目,在选择maven_archetype_webapp原型后,默认只有src/main/resources这个Source Floder.  按照maven目录结 ...

  2. 2015_WEB页面前端工程师_远程测题_东方蜘蛛_1

    请使用HTML+CSS实现如下效果: 1. 使用CSS Sprites,实现如图1效果,素材图片为: icons.png: 2. 使用脚本语言验证邮箱.密码的必填以及邮箱的合法性: 若验证失败,则出现 ...

  3. android工程混淆和反编译

    一.工程文件的混淆 混淆文件下载:http://download.csdn.net/detail/lxq_xsyu/6328751 1.在根目录下添加progard.cfg文件 2.打开project ...

  4. BZOJ2134: 单选错位

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2134 题解:因为每个答案之间是互不影响的,所以我们可以挨个计算. 假设当前在做 i 题目,如果 ...

  5. Linux Shell编程(13)——数字常量

    除非一个数字有特别的前缀或符号,否则shell脚本把它当成十进制的数.一个前缀为0的数字是八进制数.一个前缀为0x的数字是十六进制数.一个数用内嵌的#来求值则看成BASE#NUMBER(有范围和符号限 ...

  6. 【转】Android ROM研究---Android build system增加模块

    原文网址:http://hualang.iteye.com/blog/1141315 Android build system就是编译系统的意思 在我们需要向自己编译的源代码中增加模块的时候,需要一些 ...

  7. mysql 学习(1)

    1.从图中看到mysql是客户服务器模式. 2.我们如何操纵数据库? a.直接sql,各种编程语言, 3.客户端和服务器如何通信呢? 凡是c/s模式的都会自己的协议,但是都是基于TCP/IP协议,在l ...

  8. bzoj 1026 [SCOI2009]windy数(数位DP)

    1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4550  Solved: 2039[Submit][Sta ...

  9. 《University Calculus》-chape10-向量与空间几何学-向量夹角

    点积.向量夹角: 无论对于空间向量还是平面向量,我们所熟知的是:给出任意两个向量,我们都能够根据公式计算它们的夹角,但是这个夹角必须是将两个向量的起点重合后所夹成的小于等于π的角,可是,这是为什么呢? ...

  10. hdu 4284 状态压缩

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4284 #include<cstdio> #include<cstring> # ...