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

[Team] Testing Koin 2.0.0 #298

Closed
arnaudgiuliani opened this issue Nov 24, 2018 · 20 comments
Closed

[Team] Testing Koin 2.0.0 #298

arnaudgiuliani opened this issue Nov 24, 2018 · 20 comments

Comments

@arnaudgiuliani
Copy link
Member

Hello all :)

Koin 2.0.0-alpha-2 has been published in jcenter 👍 Here is how you can test it.

  • Starting Koin with the new DSL:
// Coffee Maker example
fun main(vararg args: String) {
    // declare a KoinApplication
    koinApplication {
        // enable INFO logger
        useLogger()
        // load Koin modules
        loadModules(coffeeAppModule)
    }.start() // don't forget to start it, to setup it in StandAlone Koin Application

    // ...
}
  • Starting an Android app with the new Koin DSL:
class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        // start Koin context
        koinApplication {
            // Use Android Logger
            useAndroidLogger(Level.DEBUG)
            // Use Android Context from MainApplication
            useAndroidContext(this@MainApplication)
            // Load modules
            loadModules(myModule)
        }.start() // don't forget to start it
    }
}
  • Starting Koin with Ktor:
fun Application.main() {
    // Install Ktor features
    install(DefaultHeaders)
    install(CallLogging)
    // install Koin Application
    installKoin(koinApplication {
        useLogger(logger = SLF4JLogger())
        loadModules(helloAppModule)
    })

    //...
}
  • Modules (no more inner module and name for module)
val myModule = module {
     // single, factory, scope, viewModel
}
  • Binding & names are clearly logged:
module {
    // resolved by name "default"
    single<Simple.ComponentInterface1>("default") { Simple.Component2() }
    // Resolved by type Simple.ComponentInterface1
    single<Simple.ComponentInterface1> { Simple.Component1() }
}
[INFO] [Koin] bind name:'default' ~ Single[name:'default', type:'org.koin.Simple.ComponentInterface1']
[INFO] [Koin] bind type:'org.koin.Simple.ComponentInterface1' ~ Single[type:'org.koin.Simple.ComponentInterface1']
  • Same API But changes import: inject(), get(), getViewModel(), viewModel() ... Also note that you can request by KClass with get() (check function signature)

  • Scope group declaration

module {
     withScope(SCOPE_ID) {
         scoped { Simple.ComponentA() }
         scoped { Simple.ComponentB(get()) }
     }
}
  • Module check: checkModules() is available on a KoinApplication
val mockedAndroidContext = mock(Application::class.java)

    @Test
    fun testRemoteConfiguration() {
        koinApplication {
            useAndroidContext(mockedAndroidContext)
            loadModules(onlineWeatherApp)
        }.checkModules()
    }
  • Mock & Testing:
val coffeeKoinApp = koinApplication {
    useLogger()
    loadModules(coffeeAppModule)
}

class CoffeeMakerTest : AutoCloseKoinTest() {

    private val coffeeMaker: CoffeeMaker by inject()
    private val heater: Heater by inject()

    @Before
    fun before() {
        coffeeKoinApp.start()

        declareMock<Heater> {
            given(isHot()).will { true }
        }
    }

    @Test
    fun testHeaterIsTurnedOnAndThenOff() {

        coffeeMaker.brew()

        verify(heater, times(1)).on()
        verify(heater, times(1)).off()
    }
}
  • Koin instance isolation:
val app1 = koinApplication {
    loadModules(
        module {
            single { Simple.ComponentA() }
        })
}

val app2 = koinApplication {
    loadModules(
        module {
            single { Simple.ComponentA() }
        })
}

val a1: Simple.ComponentA = app1.koin.get()
val a2: Simple.ComponentA = app2.koin.get()
// a1 & a2 not equals
  • Koin from Java:
KoinApplication.create()
                .useLogger()
                .loadModules(koinModule)
                .start();
  • Koin extensions still available:
val MVPModule = module {
        single<Repository>()
        single<View>()
        single<Presenter>()
    }

Feel free to give your feedback!

Cheers.

@westonal
Copy link

westonal commented Nov 24, 2018

// don't forget to start it

why do I have to start it in a separate step? Or phrased another way: when would one not want to start it?

DSL style:

al app2 = koinApplication {
    loadModules(
        module {

You are mixing imperative and declarative styles. It think DSLs read nicest when they stick to declarative. i.e. loadModules and useLogger feel out of place.

Compare to:

 koinApplication {
            // Use Android Logger
            androidLogger(Level.DEBUG)
            // Use Android Context from MainApplication
            androidContext(this@MainApplication)
            // Load modules
            modules(myModule)
        }

@arnaudgiuliani
Copy link
Member Author

why do I have to start it in a separate step? Or phrased another way: when would one not want to start it?

start() on a KoinApplication register it in the StandAloneContext and allow default use of Koin (by inject() ...).
A better naming with that also? register() or toStandalone()?

it think DSLs read nicest when they stick to declarative

ok, yep :)

@Sloy
Copy link

Sloy commented Nov 26, 2018

Hi! I updated my performance test project with the new alpha: https://github.com/Sloy/android-dependency-injection-performance/compare/koin2

Here are some results in a low end device: Samsung j5nlte with Android 6.0.1

The improvement is huge. There might be room for improvement still, but at least it feels production-ready in terms of performance.
Also, there's still that strange impact when loading Java classes. I'm not sure where's that coming from.

Test: Koin 1.0.1 + Kotlin
Startup: 1121,12 ms
Min-Max: 268,89-290,61 ms
Average: 271,42 ms
Test: Koin 1.0.1 + Java
Startup: 1578,65 ms
Min-Max: 404,19-416,20 ms
Average: 406,65 ms
Test: Koin 2.0.0 + Kotlin
Startup: 709,51 ms
Min-Max: 11,80-19,02 ms
Average: 12,41 ms
Test: Koin 2.0.0 + Java
Startup: 1423,47 ms
Min-Max: 11,97-16,32 ms
Average: 12,48 ms
Test: Kodein + Kotlin
Startup: 535,60 ms
Min-Max: 8,24-16,70 ms
Average: 8,60 ms
Test: Kodein + Java
Startup: 506,22 ms
Min-Max: 8,78-11,80 ms
Average: 9,11 ms
Test: Dagger2 + Kotlin
Startup: 41,53 ms
Min-Max: 0,24-6,26 ms
Average: 0,31 ms
Test: Dagger2 + Java
Startup: 41,21 ms
Min-Max: 0,21-6,02 ms
Average: 0,28 ms
Test: Custom + Kotlin
Startup: 408,04 ms
Min-Max: 0,68-0,82 ms
Average: 0,70 ms
Test: Custom + Java
Startup: 405,69 ms
Min-Max: 0,82-1,05 ms
Average: 0,84 ms

@arnaudgiuliani
Copy link
Member Author

Cool. Thanks for your benchmark.

@arnaudgiuliani
Copy link
Member Author

arnaudgiuliani commented Dec 2, 2018

Hi, here is a new perfs improvments with 2.0.0-alpha-3

Here some new perfs, done with the sloy app on my LG G4 (helped me fixed some perfs again):

I/DI-TEST: **Custom** | 3,18 ms | 3,38 ms  | 0,52 ms | 0,61 ms
I/DI-TEST: **Katana** | 8,83 ms | 8,34 ms  | 1,57 ms | 1,46 ms
I/DI-TEST: **Koin** | 40,55 ms | 40,08 ms  | 1,81 ms | 1,80 ms
I/DI-TEST: **Kodein** | 57,77 ms | 59,23 ms  | 6,14 ms | 6,06 ms
I/DI-TEST: **Dagger** | 0,01 ms | 0,01 ms  | 0,18 ms | 0,15 ms

(seems that Dagger's resolution is already done - should be at least need the time to create all graph object)
@Sloy I have some suggestions for your test: arnaudgiuliani/android-dependency-injection-performance@a4571d3

--

Starting DSL is now like more declarative:

fun main(vararg args: String) {

    startKoin {
        logger()
        modules(coffeeAppModule)
    }

}

I've have a now introduced the GlobalContext concept to replace the old StandAloneContext which tells more what is it clearly now: a global context resolution.

Let's add the Androidx Fragment factory next!

I need to make some doc now :)

@Sloy
Copy link

Sloy commented Dec 3, 2018

@arnaudgiuliani thanks for the tip! I just changed the code an the stats. Nice improvement on alpha-3 👍 👏

@erickok
Copy link
Contributor

erickok commented Dec 18, 2018

So far so good. Tested on an app woth (so far) ~350 definitions. Minor changes were required only.

@R4md4c
Copy link

R4md4c commented Dec 27, 2018

I've tried 2.0.0 and seems that there is something broken with the scopes.

I have a BaseFragment that does bindScope(getOrCreateScope(SCOPE_FRAGMENT)).
And have a fragment stack (extending BaseFragment) of fragments A->B.

With Koin 2.0.0, when I keep popping the stack by pressing back to return to launcher it crashes with this exception.

java.lang.RuntimeException: Unable to destroy activity {de.r4md4c.gamedealz/de.r4md4c.gamedealz.home.HomeActivity}: java.lang.RuntimeException: Failed to call observer method
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4458)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4476)
        at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:39)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.RuntimeException: Failed to call observer method
        at androidx.lifecycle.ClassesInfoCache$MethodReference.invokeCallback(ClassesInfoCache.java:225)
        at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeMethodsForEvent(ClassesInfoCache.java:193)
        at androidx.lifecycle.ClassesInfoCache$CallbackInfo.invokeCallbacks(ClassesInfoCache.java:184)
        at androidx.lifecycle.ReflectiveGenericLifecycleObserver.onStateChanged(ReflectiveGenericLifecycleObserver.java:36)
        at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:355)
        at androidx.lifecycle.LifecycleRegistry.backwardPass(LifecycleRegistry.java:309)
        at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:328)
        at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:138)
        at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:124)
        at androidx.fragment.app.Fragment.performDestroy(Fragment.java:2693)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1016)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1229)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1295)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2605)
        at androidx.fragment.app.FragmentManagerImpl.dispatchDestroy(FragmentManagerImpl.java:2596)
        at androidx.fragment.app.Fragment.performDestroy(Fragment.java:2695)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1016)
        at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1229)
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1295)
        at androidx.fragment.app.FragmentManagerImpl.dispatchStateChange(FragmentManagerImpl.java:2605)
        at androidx.fragment.app.FragmentManagerImpl.dispatchDestroy(FragmentManagerImpl.java:2596)
        at androidx.fragment.app.FragmentController.dispatchDestroy(FragmentController.java:318)
        at androidx.fragment.app.FragmentActivity.onDestroy(FragmentActivity.java:354)
        at androidx.appcompat.app.AppCompatActivity.onDestroy(AppCompatActivity.java:211)
        at android.app.Activity.performDestroy(Activity.java:7395)
        at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1306)
        at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4443)
        at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4476) 
        at android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:39) 
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
     Caused by: java.lang.IllegalStateException: Scope not found 'd023d781-7f16-4358-ac91-13d8ac5e3327'
        at org.koin.core.Koin.closeScope$koin_core(Koin.kt:182)
        at org.koin.core.scope.Scope.close(Scope.kt:41)
        at org.koin.androidx.scope.ScopeObserver.onDestroy(ScopeObserver.kt:54)

I believe that is because Koin has already closed this scope when fragment B was popped.

With Koin 1.0.2 this crash doesn't happen.

@arnaudgiuliani
Copy link
Member Author

Scope API is still in progress 👍

@kenyee
Copy link

kenyee commented Jan 11, 2019

For Java, can there be @Inject annotation support instead of needing to do this?
private Lazy presenter = inject(MySimplePresenter.class);

@arnaudgiuliani
Copy link
Member Author

no annotation processing in Koin's target for now.

@edwardhuerta
Copy link

edwardhuerta commented Jan 11, 2019

One of the reasons I use Koin is to avoid annotation processing. Will it be optional in the planned future releases?

@erickok
Copy link
Contributor

erickok commented Jan 11, 2019

There is nothing to be made optional, because there is no annotation processing at all. And indeed there should not be (imho). Any such thing could, if one wants it, be made as a seperate library.

@IgorGanapolsky
Copy link

IgorGanapolsky commented Mar 7, 2019

For some reaason the koinApplication api doesn't work for me. I get this compilation error:
koinApplication { modules(coreModules + libModules + featureModules) }.checkModules()

None of the following functions can be called with the arguments supplied.

@mahmed1987
Copy link

I am using the latest Koin version 2.0.0-rc-1 and have a simple test case in my androidTest folder.

class UserTestCase : KoinTest
{

    @Before
    fun before()
    {
        startKoin {
            modules(testModule1)
        }
    }

    @After
    fun after()
    {
        stopKoin()
    }

    @Test
    fun test()
    {

    }
}

val testModule1= module {

    single{ User(1,"Random","Random",false)}
}

I get "A Koin Application has already been started". Is this because my main application class also has a startKoin over there?.

@kenyee
Copy link

kenyee commented Mar 28, 2019

in our tests, I always call stopKoin before startKoin...don't do it in the @after

@ispbox
Copy link

ispbox commented Apr 29, 2019

I get "A Koin Application has already been started". Is this because my main application class also has a startKoin over there?.

Yes, it is the most relevant reason in case you use instrumented tests (they are executed on android device and thus android application class is instantiated => it causes Koin initialization as a side effect.

In unit tests you should initialize Koin by yourself.

@NurseyitTursunkulov
Copy link

No tests found for given includes: HelloAppTest when I want to run sample test. Can you help please

@prabhu73
Copy link

java.lang.IllegalStateException: No Koin Context configured. Please use startKoin or koinApplication DSL.

`@ExperimentalCoroutinesApi
@InternalCoroutinesApi
class OmdbServicesTest : AutoCloseKoinTest() {

@get:Rule
var rule = InstantTaskExecutorRule()

@get:Rule
var mockWebServer = MockWebServerRule()

private val mockedApplication = mock(OmdbApplication::class.java)

private val service: OMDBRemoteServices = get()

@Before
fun before() {
    val serviceModule by lazy {
        module {
            fun provideGson(): Gson =
                GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create()

            fun provideOkHttpClient(): OkHttpClient =
                OkHttpClient.Builder()
                    .build()

            fun provideOmdbService(): OMDBRemoteServices =
                Retrofit.Builder()
                    .baseUrl(BuildConfig.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create(get()))
                    .client(get())
                    .build()
                    .create(OMDBRemoteServices::class.java)

            single { provideGson() }
            single { provideOkHttpClient() }
            single { provideOmdbService() }
        }
    }

    stopKoin()
    startKoin {
        androidContext(mockedApplication)
        modules(serviceModule)
    }
}

@Test
fun omdbListTest() {
    val execute = service.getOmdbSearchData(
        BuildConfig.API_KEY,
        "friend",
        1
    ).execute()
    assertTrue(execute.isSuccessful && execute.body() != null)
}

}`

I am getting the below while executing the above test class

`java.lang.IllegalStateException: No Koin Context configured. Please use startKoin or koinApplication DSL.

at org.koin.core.context.KoinContextHandler.getContext(KoinContextHandler.kt:29)
at org.koin.core.context.KoinContextHandler.get(KoinContextHandler.kt:35)
at org.koin.core.KoinComponent$DefaultImpls.getKoin(KoinComponent.kt:32)
at org.koin.test.KoinTest$DefaultImpls.getKoin(KoinTest.kt)
at org.koin.test.AutoCloseKoinTest.getKoin(AutoCloseKoinTest.kt:26)
at com.myomdbapplication.service.OmdbServicesTest.<init>(OmdbServicesTest.kt:86)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:250)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:260)
at org.junit.runners.BlockJUnit4ClassRunner$2.runReflectiveCall(BlockJUnit4ClassRunner.java:309)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)`

@arora-ankit1
Copy link

java.lang.IllegalStateException: No Koin Context configured. Please use startKoin or koinApplication DSL.

`@ExperimentalCoroutinesApi
@InternalCoroutinesApi
class OmdbServicesTest : AutoCloseKoinTest() {

@get:Rule
var rule = InstantTaskExecutorRule()

@get:Rule
var mockWebServer = MockWebServerRule()

private val mockedApplication = mock(OmdbApplication::class.java)

private val service: OMDBRemoteServices = get()

@Before
fun before() {
    val serviceModule by lazy {
        module {
            fun provideGson(): Gson =
                GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create()

            fun provideOkHttpClient(): OkHttpClient =
                OkHttpClient.Builder()
                    .build()

            fun provideOmdbService(): OMDBRemoteServices =
                Retrofit.Builder()
                    .baseUrl(BuildConfig.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create(get()))
                    .client(get())
                    .build()
                    .create(OMDBRemoteServices::class.java)

            single { provideGson() }
            single { provideOkHttpClient() }
            single { provideOmdbService() }
        }
    }

    stopKoin()
    startKoin {
        androidContext(mockedApplication)
        modules(serviceModule)
    }
}

@Test
fun omdbListTest() {
    val execute = service.getOmdbSearchData(
        BuildConfig.API_KEY,
        "friend",
        1
    ).execute()
    assertTrue(execute.isSuccessful && execute.body() != null)
}

}`

I am getting the below while executing the above test class

`java.lang.IllegalStateException: No Koin Context configured. Please use startKoin or koinApplication DSL.

at org.koin.core.context.KoinContextHandler.getContext(KoinContextHandler.kt:29)
at org.koin.core.context.KoinContextHandler.get(KoinContextHandler.kt:35)
at org.koin.core.KoinComponent$DefaultImpls.getKoin(KoinComponent.kt:32)
at org.koin.test.KoinTest$DefaultImpls.getKoin(KoinTest.kt)
at org.koin.test.AutoCloseKoinTest.getKoin(AutoCloseKoinTest.kt:26)
at com.myomdbapplication.service.OmdbServicesTest.<init>(OmdbServicesTest.kt:86)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:250)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:260)
at org.junit.runners.BlockJUnit4ClassRunner$2.runReflectiveCall(BlockJUnit4ClassRunner.java:309)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)`

try checking that have you registered the Application in manifest file and use androidLogger(Level.ERROR)
for logging it worked for me, I was getting the same error

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