我有这样一个单身人士:
public class SingletonA{
private SingletonA instance = null;
private SingletonA(){
}
public static SingletonA getInstance(){
return instance ;
}
public static void init(){
System.loadLibrary("alib");
instance = new SingletonA();
}
......
other methods
}
正如您所看到的,在使用之前,我必须调用SingletonA.init()。但是Robolectric无法加载 .so 文件。我想编写一个ShadowSingletonA来替换它,但不知道该怎么做。因为变量实例是私有的。任何人都可以帮忙吗?此外,SingletonA类来自某些第三方库,因此我无法对其进行任何修改。
答案 0 :(得分:0)
这是我让它可测试的方法。 我们主要在应用程序类中初始化第三方库。在某种程度上:
public class MyApplication {
public void onCreate() {
initSomeLibrary();
}
@VisibleForTests
@RestrictTo(RestrictTo.Scope.TESTS)
protected void initSomeLibrary() {
SomeLibrary.init(this);
}
}
除非您已完成,否则Robolectric将始终尝试加载清单中指定的应用:
@Config
where you defined another app class name 因此,在这两种情况下,您都必须创建自定义应用程序应用程序。从历史上看,第一个选项早先可用,所以我坚持下去。但是,它需要有关Robolectric的知识,所以我现在将我的测试应用程序类放到@Config
部分(因此不再需要测试):
public class TestMyApplication {
protected void initSomeLibrary() {
//nothing to do
}
}
答案 1 :(得分:0)
处理依赖关系的另一种常见方法是抽象它们,使它们可以互换和可测试。
假设你有一个很棒的库,下一个API:
class LibraryName {
public static SomeSinglethon getInstance();
}
首先,创建抽象:
public class LibraryGenericPurpose {
public void doSomeThing(@NonNull String nameOfThing) {
LibraryName.getInstance().doSomething(new Event(nameOfThing));
}
}
首先请注意,该方法不是静态的,因此您必须在刚刚从库中调用静态方法的所有位置添加额外的依赖项。有时候为这样的东西设置界面也很方便。
现在你改变了一个使用它的地方:
class SomeClass {
public void someMethod() {
LibraryName.getInstance().doSomething(new Event(nameOfThing));
}
}
为:
class SomeClass {
@NonNull private LibraryGenericPurpose library;
public SomeClass(@NonNull LibraryGenericPurpose library) {
this.library = library;
}
public void someMethod() {
library.doSomeThing("Great!");
}
}
如果您无法将类生命周期控制为Activity
或Fragment
,那么您必须学习如何在那里注入依赖项的新方法。
最后,在测试中,您根本不需要使用Robolectric SomeClass
。通常,像LibraryGenericPurpose
这样的类在JVM上是不可测试的(即使使用 Robolectric ),并且在仪器测试中很难或不可能进行测试。