Skip to content

Instantly share code, notes, and snippets.

@Sarthak2601
Last active August 9, 2020 20:48
Show Gist options
  • Save Sarthak2601/a5ffdc766b1c13759afba81de196bace to your computer and use it in GitHub Desktop.
Save Sarthak2601/a5ffdc766b1c13759afba81de196bace to your computer and use it in GitHub Desktop.
@RunWith(AndroidJUnit4::class)
@Config(manifest = Config.NONE)
class ExceptionsControllerTest {
@Rule
@JvmField
val mockitoRule: MockitoRule = MockitoJUnit.rule()
@Inject
lateinit var exceptionsController: ExceptionsController
@Inject
lateinit var networkConnectionUtil: NetworkConnectionUtil
@Inject
lateinit var fakeExceptionLogger: FakeExceptionLogger
@InternalCoroutinesApi
@Inject
lateinit var testCoroutineDispatchers: TestCoroutineDispatchers
@Mock
lateinit var mockOppiaExceptionLogsObserver: Observer<AsyncResult<OppiaExceptionLogs>>
@Captor
lateinit var oppiaExceptionLogsResultCaptor: ArgumentCaptor<AsyncResult<OppiaExceptionLogs>>
@Inject
@field:TestDispatcher
lateinit var testDispatcher: CoroutineDispatcher
private val coroutineContext by lazy {
EmptyCoroutineContext + testDispatcher
}
// https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-test/
@ObsoleteCoroutinesApi
private val testThread = newSingleThreadContext("TestMain")
private val exceptionThrown = Exception("TEST MESSAGE", Throwable("TEST CAUSE"))
@Before
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
fun setUp() {
networkConnectionUtil = NetworkConnectionUtil(ApplicationProvider.getApplicationContext())
Dispatchers.setMain(testThread)
setUpTestApplicationComponent()
}
@After
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
fun tearDown() {
Dispatchers.resetMain()
testThread.close()
}
@ExperimentalCoroutinesApi
@InternalCoroutinesApi
@Test
fun testController_logException_nonFatal_withNoNetwork_logsToCacheStore() =
runBlockingTest(testDispatcher){
networkConnectionUtil.setCurrentConnectionStatus(NetworkConnectionUtil.ConnectionStatus.NONE)
exceptionsController.logNonFatalException(exceptionThrown, TEST_TIMESTAMP_IN_MILLIS_ONE)
val cachedExceptions = exceptionsController.getExceptionLogs()
advanceUntilIdle()
val exceptionLog = cachedExceptions.getExceptionLog(0)
advanceUntilIdle()
val exception = exceptionLog.toException()
advanceUntilIdle()
assertThat(exception.message).isEqualTo(exceptionThrown.message)
assertThat(exception.stackTrace).isEqualTo(exceptionThrown.stackTrace)
assertThat(exception.cause?.message).isEqualTo(exceptionThrown.cause?.message)
assertThat(exception.cause?.stackTrace).isEqualTo(exceptionThrown.cause?.stackTrace)
assertThat(exceptionLog.exceptionType).isEqualTo(ExceptionType.NON_FATAL)
}
private fun setUpTestApplicationComponent() {
DaggerExceptionsControllerTest_TestApplicationComponent.builder()
.setApplication(ApplicationProvider.getApplicationContext())
.build()
.inject(this)
}
@Qualifier
annotation class TestDispatcher
// TODO(#89): Move this to a common test application component.
@Module
class TestModule {
@Provides
@Singleton
fun provideContext(application: Application): Context {
return application
}
@ExperimentalCoroutinesApi
@Singleton
@Provides
@TestDispatcher
fun provideTestDispatcher(): CoroutineDispatcher {
return TestCoroutineDispatcher()
}
// TODO(#59): Either isolate these to their own shared test module, or use the real logging
// module in tests to avoid needing to specify these settings for tests.
@EnableConsoleLog
@Provides
fun provideEnableConsoleLog(): Boolean = true
@EnableFileLog
@Provides
fun provideEnableFileLog(): Boolean = false
@GlobalLogLevel
@Provides
fun provideGlobalLogLevel(): LogLevel = LogLevel.VERBOSE
}
@Module
class TestLogStorageModule {
@Provides
@ExceptionLogStorageCacheSize
fun provideExceptionLogStorageCacheSize(): Int = 2
}
// TODO(#89): Move this to a common test application component.
@Singleton
@Component(
modules = [
TestModule::class, TestLogReportingModule::class,
TestDispatcherModule::class, TestLogStorageModule::class
]
)
interface TestApplicationComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun setApplication(application: Application): Builder
fun build(): TestApplicationComponent
}
fun inject(exceptionsControllerTest: ExceptionsControllerTest)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment