Android 如何使用Robolectic跟踪singleton?
我有这样一个单身汉:Android 如何使用Robolectic跟踪singleton?,android,singleton,robolectric,Android,Singleton,Robolectric,我有这样一个单身汉: public class SingletonA{ private SingletonA instance = null; private SingletonA(){ } public static SingletonA getInstance(){ return instance ; } public static void init(){ System
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无法加载。因此文件。我想写一个ShadowSingletonA来替换它,但不知道怎么做。因为变量实例是私有的。有人能帮忙吗?此外,SingletonA类来自某个第三方库,因此我无法对其进行任何修改。以下是我使其可测试的方法。 我们主要在应用程序类中初始化第三方库。在某种程度上:
public class MyApplication {
public void onCreate() {
initSomeLibrary();
}
@VisibleForTests
@RestrictTo(RestrictTo.Scope.TESTS)
protected void initSomeLibrary() {
SomeLibrary.init(this);
}
}
Robolectric将始终尝试加载清单中指定的应用程序,除非您完成以下操作:
因此,在这两种情况下,您都必须创建自定义应用程序。从历史上看,第一个选项在更早的时候就可用,所以我坚持使用它。但是,它需要有关Robolectric的知识,因此我现在将我的测试应用程序类放在@Config
部分(因此不再需要测试):
以下是我的方法,使其可测试。 我们主要在应用程序类中初始化第三方库。在某种程度上:
public class MyApplication {
public void onCreate() {
initSomeLibrary();
}
@VisibleForTests
@RestrictTo(RestrictTo.Scope.TESTS)
protected void initSomeLibrary() {
SomeLibrary.init(this);
}
}
Robolectric将始终尝试加载清单中指定的应用程序,除非您完成以下操作:
因此,在这两种情况下,您都必须创建自定义应用程序。从历史上看,第一个选项在更早的时候就可用,所以我坚持使用它。但是,它需要有关Robolectric的知识,因此我现在将我的测试应用程序类放在@Config
部分(因此不再需要测试):
处理依赖关系的另一种常见方法是抽象它们,使它们可以互换和测试 因此,假设您拥有具有下一个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));
}
}
致:
如果你不能像活动
或片段
那样控制类的生命周期,那么你必须学习如何在那里注入依赖项的新方法
最后,在测试中,您根本不需要为
SomeClass
使用Robolectric。通常,像LibraryGenericPurpose
这样的类在JVM上是不可测试的(即使使用Robolectric),并且很难或不可能在仪器测试中进行测试。另一种处理依赖关系的常用方法是将它们抽象出来,使它们可以互换和测试
因此,假设您拥有具有下一个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));
}
}
致:
如果你不能像活动
或片段
那样控制类的生命周期,那么你必须学习如何在那里注入依赖项的新方法
最后,在测试中,您根本不需要为
SomeClass
使用Robolectric。很多时候,像LibraryGenericPurpose
这样的类在JVM上是不可测试的(即使使用Robolectric),并且很难或不可能在仪器测试中进行测试。是的,我已经在UT案例中使用自定义应用程序来避免加载“.so”文件。但最近,我得到了一个名为EZOpenSDK的单例模式类,它在构造函数中运行System.loadLibrary()。这让我可以在UT中创建这个类的实例。所以我想创建一个ShadowEZOpenSDK来替换它。但我不知道如何在我的ShadowEZOpenSDK中处理方法public static EZOpenSDK getInstance()。然后我会写另一个答案:)你太好了。是的,我已经在UT案例中使用了自定义应用程序来避免加载“.so”文件。但最近,我得到了一个名为EZOpenSDK的单例模式类,它在构造函数中运行System.loadLibrary()。这让我可以在UT中创建这个类的实例。所以我想创建一个ShadowEZOpenSDK来替换它。但是我不知道如何在我的ShadowEZOpenSDK中处理方法public static EZOpenSDK getInstance()。