为React-native原生android方法编写单元测试

Har*_*ana 5 android unit-testing react-native react-native-android react-native-native-module

我正在构建具有一些本地android模块的react-native应用程序。
在MainApplication.java中,

protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        new VectorIconsPackage(),
        new MyCustomPackage()
    );
  }
Run Code Online (Sandbox Code Playgroud)

在我的MyCustomPackage中,

public class MyCustomPackage implements ReactPackage {

  @Override
  public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
    return Collections.emptyList();
  }

  @Override
  public List<NativeModule> createNativeModules(
                              ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();

    modules.add(new MyCustomModule(reactContext));

    return modules;
  }

}
Run Code Online (Sandbox Code Playgroud)

我还有其他几个模块,但这只是一个例子。所有功能都运作良好。现在,我想向MyCustomModule Java类中的方法编写单元测试。我尝试使用Robolectric框架,但不知道它如何与react native一起工作。还有其他工具吗?谁能给我一些示例或指导,以编写本机原生Android代码的单元测试?

nuK*_*uKs 2

使用Robolectric 4。

看我的评论。

我这样做的方式是

  1. 模拟应用程序以删除不兼容的依赖项加载。
  2. 将 ApplicationContext 包装在 ReactApplicationContext 中以实例化该模块。

可能需要 @Config 和自定义应用程序内容来删除 robolectric 未处理的二进制依赖项,例如 Bugsnag 和通用 soloader。如果你的所有依赖项都可用于你的开发环境系统架构(这是非常不可能的),那么也许没有它就可以工作。

@RunWith(AndroidJUnit4.class)
@Config(
    application = TestApplication.class
)
public class ReactModuleSpec {

    private ReactModule reactModule;

    @Before
    public void beforeEach() {
        // Retrieve application context.
        Context applicationContext = ApplicationProvider.getApplicationContext();

        // Recreate ReactApplicationContext which ReactModule depends upon.
        // ReactApplicationContext sole purpose as documented in its source code
        // is to preserve type integrity of ApplicationContext over Context
        // (which android Context obviously does not). This should be safe
        // thus. See my post here:
        // `https://stackoverflow.com/questions/49962298/writing-unit-test-for-react-native-native-android-methods`.
        ReactApplicationContext reactApplicationContext = new ReactApplicationContext(applicationContext);

        // Instantiate the module.
        reactModule = new ReactModule(reactApplicationContext);
    }

    // ...

}
Run Code Online (Sandbox Code Playgroud)
public class TestApplication extends Application implements ReactApplication {

    // ...

    // Remove packages incompatible with Robolectric.
    @Override
    protected List<ReactPackage> getPackages() {
        List<ReactPackage> packages = new PackageList(this).getPackages();

        // ... Your standard stuffs

        packages.removeIf(pkg -> pkg.getClass().isInstance(BugsnagReactNative.getPackage().getClass()));

        return packages;
    }

    // Remove soloader !
    @Override
    public void onCreate() {
        super.onCreate();

        // Bye bye!
        // BugsnagReactNative.start(this);
        // SoLoader.init(this, /* native exopackage */ false);
    }
}
Run Code Online (Sandbox Code Playgroud)