单元测试 WritableNativeMap 时出现 UnsatisfiedLinkError
UnsatisfiedLinkError when unit testing WritableNativeMap
我目前正在创建一个 Android 库以用于 React Native 项目。我需要将地图发送到 javascript,所以我使用的是 React Native 的 WriteableMap class。不幸的是,class 在静态块中加载 reactnativejni SO,这导致单元测试期间出现 UnsatisfiedLinkError。我正在使用 JUnit 和 Mockito 进行测试。
我的代码:
@Override
public void onSomething() {
WritableMap params = Arguments.createMap();
//fill map
sendEvent("onChange", params);
}
错误:
java.lang.UnsatisfiedLinkError: no reactnativejni in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1119)
at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:172)
at com.facebook.react.bridge.NativeMap.<clinit>(NativeMap.java:23)
at com.facebook.react.bridge.Arguments.createMap(Arguments.java:29)
at me.MyClass.onSomething(myClass.java:23)
在看到关于为单元测试存根 WriteableMap 的评论后,我开始使用 Arguments.createMap()
方法,但它是静态的,我宁愿不必存根静态方法。
在 运行 单元测试时有什么方法可以消除这个错误吗?
我认为您无法避免在单元测试中模拟 Arguments 方法(尽管我相信您不需要在仪器测试中这样做)。
在 Facebook 自己的测试中,他们使用 PowerMockito
来模拟它们:
https://github.com/facebook/react-native/blob/master/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java#L67
有趣的位:
PowerMockito.mockStatic(Arguments.class);
PowerMockito.when(Arguments.createArray()).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return new JavaOnlyArray();
}
});
PowerMockito.when(Arguments.createMap()).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return new JavaOnlyMap();
}
});
另请注意,这需要您修改 build.gradle
以包含这些模拟工具:
https://github.com/facebook/react-native/blob/master/ReactAndroid/build.gradle#L266
dependencies {
...
testCompile "org.powermock:powermock-api-mockito:${POWERMOCK_VERSION}"
testCompile "org.powermock:powermock-module-junit4-rule:${POWERMOCK_VERSION}"
testCompile "org.powermock:powermock-classloading-xstream:${POWERMOCK_VERSION}"
testCompile "org.mockito:mockito-core:${MOCKITO_CORE_VERSION}"
testCompile "org.easytesting:fest-assert-core:${FEST_ASSERT_CORE_VERSION}"
testCompile "org.robolectric:robolectric:${ROBOLECTRIC_VERSION}"
...
}
他们使用的版本可以在他们的 gradle.properties
文件中找到。
我不知道这些测试配置在长期 运行 中的稳定性如何,但这种配置让我可以在单元测试中使用 ReadableMap/Array 和 WritableMap/Array。
你也可以使用JavaOnlyMap
,它实现了WritableMap
和ReadableMap
。
所以哪里需要用到Arguments.createMap()
,就换成new JavaOnlyMap()
我目前正在创建一个 Android 库以用于 React Native 项目。我需要将地图发送到 javascript,所以我使用的是 React Native 的 WriteableMap class。不幸的是,class 在静态块中加载 reactnativejni SO,这导致单元测试期间出现 UnsatisfiedLinkError。我正在使用 JUnit 和 Mockito 进行测试。
我的代码:
@Override
public void onSomething() {
WritableMap params = Arguments.createMap();
//fill map
sendEvent("onChange", params);
}
错误:
java.lang.UnsatisfiedLinkError: no reactnativejni in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1119)
at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:172)
at com.facebook.react.bridge.NativeMap.<clinit>(NativeMap.java:23)
at com.facebook.react.bridge.Arguments.createMap(Arguments.java:29)
at me.MyClass.onSomething(myClass.java:23)
在看到关于为单元测试存根 WriteableMap 的评论后,我开始使用 Arguments.createMap()
方法,但它是静态的,我宁愿不必存根静态方法。
在 运行 单元测试时有什么方法可以消除这个错误吗?
我认为您无法避免在单元测试中模拟 Arguments 方法(尽管我相信您不需要在仪器测试中这样做)。
在 Facebook 自己的测试中,他们使用 PowerMockito
来模拟它们:
https://github.com/facebook/react-native/blob/master/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java#L67
有趣的位:
PowerMockito.mockStatic(Arguments.class);
PowerMockito.when(Arguments.createArray()).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return new JavaOnlyArray();
}
});
PowerMockito.when(Arguments.createMap()).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return new JavaOnlyMap();
}
});
另请注意,这需要您修改 build.gradle
以包含这些模拟工具:
https://github.com/facebook/react-native/blob/master/ReactAndroid/build.gradle#L266
dependencies {
...
testCompile "org.powermock:powermock-api-mockito:${POWERMOCK_VERSION}"
testCompile "org.powermock:powermock-module-junit4-rule:${POWERMOCK_VERSION}"
testCompile "org.powermock:powermock-classloading-xstream:${POWERMOCK_VERSION}"
testCompile "org.mockito:mockito-core:${MOCKITO_CORE_VERSION}"
testCompile "org.easytesting:fest-assert-core:${FEST_ASSERT_CORE_VERSION}"
testCompile "org.robolectric:robolectric:${ROBOLECTRIC_VERSION}"
...
}
他们使用的版本可以在他们的 gradle.properties
文件中找到。
我不知道这些测试配置在长期 运行 中的稳定性如何,但这种配置让我可以在单元测试中使用 ReadableMap/Array 和 WritableMap/Array。
你也可以使用JavaOnlyMap
,它实现了WritableMap
和ReadableMap
。
所以哪里需要用到Arguments.createMap()
,就换成new JavaOnlyMap()