我需要模拟一些自定义类(为它创建一个阴影)。 我已经阅读了http://robolectric.org/custom-shadows/如何做到这一点。
所以,我有一些课程:
public class MyClass {
public static int regularMethod() { return 1; }
}
我创造了一个阴影:
@Implements(MyClass.class)
public class MyShadowClass {
@Implementation
public static int regularMethod() { return 2; }
}
我在Test-class中设置了阴影:
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, shadows={MyShadowClass.class})
public class MyTest {
@Test
public void testShadow() {
assertEquals(2, MyClass.regularMethod());
}
}
但是没有使用阴影。
java.lang.AssertionError:
Expected :2
Actual :1
如何为RobolectricGradleTestRunner制作任何自定义阴影?
我已经尝试过了:
但是我得到了各种编译错误,例如
InstrumentingClassLoaderConfig
未找到Setup
未找到如何在 robolectric 3.0 中正确使用自定义阴影?
答案 0 :(得分:5)
应该避免自定义阴影,并且必须是最后的沟渠。只有在代码中无法进行太多重构时才会使用它,这会阻止您像本机方法调用一样运行测试。最好使用powermock或mockito来模拟该类或间谍的对象,而不是自定义阴影。如果它是静态方法,那么使用powermock。
在我们的项目中,我们有一个具有一些本机方法的类,它是应用程序中随处可用的配置类。所以我们将原生方法移动到另一个类并将其隐藏起来。那些原生方法在测试用例中失败了。
无论如何,你可以在robolectric 3.0中自定义阴影:
创建一个扩展RobolectricGradleTestRunner的自定义测试运行器:
public class CustomRobolectricTestRunner extends RobolectricGradleTestRunner {
public CustomRobolectricTestRunner(Class<?> klass) throws InitializationError {
super(klass);
}
public InstrumentationConfiguration createClassLoaderConfig() {
InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
builder.addInstrumentedPackage("com.yourClassPackage");
return builder.build();
}
确保程序包不包含使用robolectric运行的任何测试用例。
答案 1 :(得分:2)
我是Jiahao,你所指的第二个存储库的创建者。
首先感谢您查看我的代码。我在Android上做了很多研究,我很高兴我的研究对其他人有用。
然后,关于Robolectric的暗影。我在这个项目中使用Robolectric 3.1来测试Robolectric 3如何与MarshMallow一起工作: https://github.com/jiahaoliuliu/robolectricForMarshmallow
我一直在测试新的运行时权限管理器,以及阴影应用程序和活动。
以下是阴影活动的示例代码:
import android.content.Context;
import com.jiahaoliuliu.robolectricformarshmallow.controller.MainController;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
/**
* Created by Jiahao on 7/18/16.
*/
@Implements(MainController.class)
public class MainControllerShadow {
public void __constructor__ (Context context) {
// Not do anything
}
@Implementation
public String getTextToDisplay(boolean permissionGranted) {
return "Test";
}
}
这就是我在单元测试中使用它的方式:
包com.jiahaoliuliu.robolectricformarshmallow;
import com.jiahaoliuliu.robolectricformarshmallow.shadow.MainControllerShadow;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import static org.junit.Assert.*;
/**
* Created by Jiahao on 6/30/16.
*/
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, manifest = Config.NONE, application = FoolApplication.class,
shadows = { MainControllerShadow.class}, sdk = 18)
public class MainActivityTest {
private MainActivity mMainActivity;
@Before
public void setUp() throws Exception {
mMainActivity = Robolectric.setupActivity(MainActivity.class);
}
@After
public void tearDown() throws Exception {
}
@Test
public void testOnCreate() throws Exception {
// Simple test to know that it works
assertTrue(true);
}
}
如您所见,我没有使用自定义的Gradle Test Runner。我已经检查了Robolectric的源代码,对于版本3.0和3.1(最新版本),只需在头文件中指定阴影类就足够了。
我希望它有所帮助