Написание юнит-теста для реактивных нативных методов Android

Я создаю приложение Reaction-native, в котором есть несколько встроенных модулей Android.
В MainApplication.java,

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

В моем 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;
  }

}

У меня есть несколько других модулей, но это пример. Все функции работают хорошо. Теперь я хочу написать модульный тест для методов, которые находятся в Java-классе MyCustomModule. Я пытаюсь использовать фреймворк Robolectric, но не знаю, как он работает с реагировать нативно. Есть ли другой инструмент для этого? Кто-нибудь может дать мне какой-нибудь пример или руководство по написанию юнит-теста для собственного кода android?

0 ответов

Использование Robolectric 4.

Смотрите мои комментарии.

Как я это делаю

  1. имитируйте приложение, чтобы удалить несовместимую загрузку зависимостей.
  2. оберните ApplicationContext в ReactApplicationContext, чтобы создать экземпляр модуля.

@Config и пользовательские компоненты Application, вероятно, потребуются для удаления двоичных зависимостей, не обрабатываемых robolectric, таких как Bugsnag и общий Solader. Возможно, можно было бы работать без, если все ваши зависимости доступны для вашей системной архитектуры dev env (что очень маловероятно).

@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://stackru.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);
    }
}