Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing unit test for react-native native android methods

I'm building react-native app which has some native android modules in it.
In MainApplication.java,

protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        new VectorIconsPackage(),
        new MyCustomPackage()
    );
  }

In my 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;
  }

}

I have few other modules but this is an example. The all functions works well. Now I want to write unit test to methods which are in the MyCustomModule java class. I try to use Robolectric framework but don't know how it's working with react native. Is there any other tool for that? Can anyone give me some example or guide in writing unit test for react-native native android code?

like image 772
Harshitha Palihawadana Avatar asked Apr 22 '18 03:04

Harshitha Palihawadana


People also ask

How do you perform a unit test in React Native app?

To do so, run yarn add jest-expo --dev or npm i jest-expo --save-dev depending on which package manager you prefer. Then, install the test renderer library: yarn add react-test-renderer --dev or npm i react-test-renderer --save-dev .

Can you use Jest with React Native?

The Jest preset built into react-native comes with a few default mocks that are applied on a react-native repository. However, some react-native components or third party components rely on native code to be rendered. In such cases, Jest's manual mocking system can help to mock out the underlying implementation.

Is detox better than Appium?

The comparison of the frameworks shows that Detox scores more points than Appium. Nevertheless, it has to be considered that the resulting ratings for the frameworks are very close to each other (112 vs. 99).

What should I test in Unit tests Android?

Unit tests or small tests only verify a very small portion of the app, such as a method or class. End-to-end tests or big tests verify larger parts of the app at the same time, such as a whole screen or user flow. Medium tests are in between and check the integration between two or more units.


1 Answers

Using Robolectric 4.

See my comments.

The way I do it is

  1. mock the Application in order to remove incompatible dependency loading.
  2. wrap the ApplicationContext in ReactApplicationContext to instantiate the module.

The @Config and custom Application stuffs are probably required to remove binary dependencies not handled by robolectric such as Bugsnag and the general soloader. Could perhaps work without if all your dependencies are available for your dev env system arch (which is very unlikely).

@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);
    }

    // ...

}
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);
    }
}
like image 123
nuKs Avatar answered Sep 30 '22 12:09

nuKs