Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE in Fresco.initialize(this) in the Application when running Robolectric Unit Test #2060

Closed
sdeira opened this issue Mar 1, 2018 · 14 comments

Comments

@sdeira
Copy link

sdeira commented Mar 1, 2018

We use GitHub Issues for bugs.

If you have a non-bug question, please ask on Stack Overflow: http://stackoverflow.com/questions/tagged/fresco

--- Please use this template, and delete everything above this line before submitting your issue ---

Description

Im trying to run a unit test using Robolectric ( testImplementation "org.robolectric:robolectric:3.7.1") and a NPE appears when executing Fresco.initialize(this) in the main Application.
This is the code of the test:

@RunWith(RobolectricTestRunner.class)
public class MainActivityTest {

    @Test
    public void testRecyclerData() {
        final MainActivity activity = Robolectric.setupActivity(MainActivity.class);
        final RecyclerView recyclerView = activity.findViewById(R.id.recycler_view_main_activity);
        final List<Show> list = new ArrayList<Show>();
        list.add(new Show());
        activity.addDataToView(list);
        Assert.assertEquals(1, recyclerView.getAdapter().getItemCount());
    }

}

Here is the stack:

java.lang.NullPointerException
	at java.io.File.<init>(File.java:277)
	at com.facebook.soloader.SoLoader.initImpl(SoLoader.java:198)
	at com.facebook.soloader.SoLoader.init(SoLoader.java:120)
	at com.facebook.soloader.SoLoader.init(SoLoader.java:104)
	at com.facebook.drawee.backends.pipeline.Fresco.initialize(Fresco.java:63)
	at com.facebook.drawee.backends.pipeline.Fresco.initialize(Fresco.java:39)
	at com.sebas.sysfishapp.videofeed.MainApplication.onCreate(MainApplication.java:16)
	at org.robolectric.android.internal.ParallelUniverse.lambda$setUpApplicationState$0(ParallelUniverse.java:204)
	at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:72)
	at org.robolectric.android.internal.ParallelUniverse.setUpApplicationState(ParallelUniverse.java:203)
	at org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:333)
	at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:245)
	at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:130)
	at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:42)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:84)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
	at com.sun.proxy.$Proxy3.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:109)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:146)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:128)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:748)

Reproduction

100%

Solution

[OPTIONAL: Do you know what needs to be done to address this issue? Ideally, provide a pull request which fixes this issue.]

Additional Information

  • Fresco version:1.8.1
  • Platform version: API 21
@foghina
Copy link
Contributor

foghina commented Mar 1, 2018

Try calling SoLoader.setInTestMode() in your test setup (@Before method). We do this in a bunch of our tests as well, see:

https://github.com/facebook/fresco/search?q=setintestmode

Let me know if this fixes the issue. We should probably document this somewhere.

@sdeira
Copy link
Author

sdeira commented Mar 1, 2018

Nop, same error.

@sdeira
Copy link
Author

sdeira commented Mar 1, 2018

@foghina the problem is that the MainApplication extends Application is called before the setUp (@before) so the SoLoader.setInTestMode() is never been called. Now, I remove the Fresco.Initialize(this) from the MainApplication and set it in the activity and Its working :) but I dont want to call Fresco.initialize(this) in all the activities on my app. Is there any workarround for this situation? Thanks

@foghina
Copy link
Contributor

foghina commented Mar 2, 2018

Hmm, MainApplication#onCreate() shouldn't be called before setUp. Perhaps you can try using @BeforeClass instead?

@erikandre
Copy link
Contributor

Hi @sdeira

Could you replace your default Application class with one used only for the tests?

it should be possible using Robolectric: https://stackoverflow.com/questions/21725309/robolectric-not-using-test-application

@BansookNam
Copy link

@sdeira I know its tricky but I solved it with try-catch.

try {
         Fresco.initialize(this, config);
       } catch (Throwable th) {
         Log.d("fresco", "error");
       }

@BansookNam
Copy link

@foghina @BeforeClass is working thanks.
and the method should be static in the TestClass

 @BeforeClass
    public static void before() throws Exception{
        SoLoader.setInTestMode();
    }

@foghina
Copy link
Contributor

foghina commented Apr 19, 2018

@BansookNam thanks for the update!

@vkotovv
Copy link

vkotovv commented Apr 26, 2019

@BansookNam SoLoader is a runtime dependency for Fresco 1.13.0. When using Gradle 5, this is now not included in compilation classpath by default (see migration guide). I had to declare it explicitly:

testImplementation 'com.facebook.soloader:soloader:0.6.0'

@harshmittal29
Copy link

@BansookNam @BeforeClass
public static void before() throws Exception{
SoLoader.setInTestMode();
}
this code did not solve the problem for me. try catch did. Is there a way to solve this without using try catch?

@BansookNam
Copy link

@vkotovv Thank you for notice!
@harshmittal29 Did you try implement
testImplementation 'com.facebook.soloader:soloader:0.6.0'
this on your build.gradle? Check vkotovv's comment.

If not working. I have no Idea how to solve 😢you may use try catch.

@danielnmai
Copy link

danielnmai commented Jul 25, 2019

Confirmed that

    @BeforeClass
    public static void setup() {
        SoLoader.setInTestMode();
    }

works for me.

@mformetal
Copy link

mformetal commented Jan 16, 2020

Is there any reason why TestNativeLoader isn't in the 2.0.0 release of Fresco?

This forces consumers to explicitly include the soloader library, which doesn't seem reasonable since Fresco already consumes it so should provide test utilities around it.

@oprisnik
Copy link
Contributor

TestNativeLoader was added with version 2.1.0 and should be available starting with that version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants