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

Fix Part of #4236 : Add tests for AsyncResultSubject #5670

Open
wants to merge 18 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions scripts/assets/test_file_exemptions.textproto
Original file line number Diff line number Diff line change
Expand Up @@ -4010,10 +4010,6 @@ test_file_exemption {
exempted_file_path: "testing/src/main/java/org/oppia/android/testing/TextInputActionTestActivity.kt"
test_file_not_required: true
}
test_file_exemption {
exempted_file_path: "testing/src/main/java/org/oppia/android/testing/data/AsyncResultSubject.kt"
test_file_not_required: true
}
test_file_exemption {
exempted_file_path: "testing/src/main/java/org/oppia/android/testing/environment/TestEnvironmentConfig.kt"
test_file_not_required: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import com.google.common.truth.extensions.proto.LiteProtoTruth.assertThat
import com.google.protobuf.MessageLite
import org.oppia.android.util.data.AsyncResult

// TODO(#4236): Add tests for this class.

/**
* Truth subject for verifying properties of [AsyncResult]s.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package org.oppia.android.testing.data

import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.oppia.android.util.data.AsyncResult
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.shadows.ShadowSystemClock

@RunWith(RobolectricTestRunner::class)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@RunWith(RobolectricTestRunner::class)
@RunWith(JUnit4::class)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried switching to JUnit4 as suggested, but I encountered an error:
java.lang.UnsatisfiedLinkError: 'long android.os.SystemClock.uptimeMillis()'.
Since this is related to Android-specific functionality, I’m reverting to RobolectricTestRunner to ensure the tests run correctly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds good, thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per yesterday’s discussion, Ben mentioned that we don’t generally use the Robolectric runner, so one way to fix this error while using the JUnit runner is to inject FakeOppiaClock in this class, and then add an @before method to initialize the FakeOppiaClock object to uptimemillis or fake time mode as needed for these tests

@Config(shadows = [ShadowSystemClock::class])
class AsyncResultSubjectTest {
private val pendingResult: AsyncResult<String> = AsyncResult.Pending()
private val successResult: AsyncResult<String> = AsyncResult.Success("Some string")
private val failureResult: AsyncResult<String> =
AsyncResult.Failure(RuntimeException("Error message"))

@Test
fun testAsyncResultSubject_pendingResult_checkIsPending() {
AsyncResultSubject.assertThat(pendingResult).isPending()
}

@Test
fun testAsyncResultSubject_pendingResult_checkIsNotSuccess() {
AsyncResultSubject.assertThat(pendingResult).isNotSuccess()
}

@Test
fun testAsyncResultSubject_pendingResult_checkIsNotFailure() {
AsyncResultSubject.assertThat(pendingResult).isNotFailure()
}

@Test
fun testAsyncResultSubject_successResult_checkIsNotPending() {
AsyncResultSubject.assertThat(successResult).isNotPending()
}

@Test
fun testAsyncResultSubject_successResult_checkIsSuccess() {
AsyncResultSubject.assertThat(successResult).isSuccess()
}

@Test
fun testAsyncResultSubject_successResult_checkIsNotFailure() {
AsyncResultSubject.assertThat(successResult).isNotFailure()
}

@Test
fun testAsyncResultSubject_successResult_checkSuccessValueMatches() {
AsyncResultSubject.assertThat(successResult).hasSuccessValueWhere {
assertThat(this).isEqualTo("Some string")
}
}

@Test
fun testAsyncResultSubject_successResult_checkIsStringSuccessThat() {
AsyncResultSubject.assertThat(successResult)
.isStringSuccessThat()
.isEqualTo("Some string")
}

@Test
fun testAsyncResultSubject_failureResult_checkIsFailure() {
AsyncResultSubject.assertThat(failureResult).isFailure()
}

@Test
fun testAsyncResultSubject_failureResult_checkIsNotSuccess() {
AsyncResultSubject.assertThat(failureResult).isNotSuccess()
}

@Test
fun testAsyncResultSubject_failureResult_checkIsNotPending() {
AsyncResultSubject.assertThat(failureResult).isNotPending()
}

@Test
fun testAsyncResultSubject_failureResult_checkErrorMessageMatches() {
AsyncResultSubject.assertThat(failureResult)
.isFailureThat()
.hasMessageThat()
.contains("Error message")
}

@Test
fun testAsyncResultSubject_twoSuccessResults_checkNewerOrSameAge() {
val successResult1: AsyncResult<String> = AsyncResult.Success("First")
val successResult2: AsyncResult<String> = AsyncResult.Success("Second")
AsyncResultSubject.assertThat(successResult1).isNewerOrSameAgeAs(successResult2)
}

@Test
fun testAsyncResultSubject_sameSuccessValue_checkHasSameEffectiveValue() {
val successResult1: AsyncResult<String> = AsyncResult.Success("Same value")
val successResult2: AsyncResult<String> = AsyncResult.Success("Same value")
AsyncResultSubject.assertThat(successResult1)
.hasSameEffectiveValueAs(successResult2)
.isTrue()
}

@Test
fun testAsyncResultSubject_differentSuccessValues_checkHasDifferentEffectiveValue() {
val successResult1: AsyncResult<String> = AsyncResult.Success("First value")
val successResult2: AsyncResult<String> = AsyncResult.Success("Second value")
AsyncResultSubject.assertThat(successResult1)
.hasSameEffectiveValueAs(successResult2)
.isFalse()
}

@Test
fun testAsyncResultSubject_intSuccess_checkIsIntSuccessThat() {
val intResult: AsyncResult<Int> = AsyncResult.Success(42)
AsyncResultSubject.assertThat(intResult)
.isIntSuccessThat()
.isEqualTo(42)
}

@Test
fun testAsyncResultSubject_booleanSuccess_checkIsBooleanSuccessThat() {
val boolResult: AsyncResult<Boolean> = AsyncResult.Success(true)
AsyncResultSubject.assertThat(boolResult)
.isBooleanSuccessThat()
.isTrue()
}

@Test
fun testAsyncResultSubject_differentFailureMessages_checkHasDifferentEffectiveValue() {
val failureResult1: AsyncResult<String> = AsyncResult.Failure(RuntimeException("Error 1"))
val failureResult2: AsyncResult<String> = AsyncResult.Failure(RuntimeException("Error 2"))
AsyncResultSubject.assertThat(failureResult1)
.hasSameEffectiveValueAs(failureResult2)
.isFalse()
}

@Test
fun testAsyncResultSubject_pendingResult_checkIsNotSuccessOrFailure() {
AsyncResultSubject.assertThat(pendingResult).isNotSuccess()
AsyncResultSubject.assertThat(pendingResult).isNotFailure()
}

@Test
fun testAsyncResultSubject_successResult_checkIsSuccessThat() {
AsyncResultSubject.assertThat(successResult).isSuccessThat().isEqualTo("Some string")
}

@Test
fun testAsyncResultSubject_failureResult_checkIsFailureThatError() {
AsyncResultSubject.assertThat(failureResult)
.isFailureThat()
.hasMessageThat()
.contains("Error message")
}

@Test
fun testAsyncResultSubject_pendingResult_checkHasSameEffectiveValueAs() {
val anotherPending: AsyncResult<String> = AsyncResult.Pending()
AsyncResultSubject.assertThat(pendingResult).hasSameEffectiveValueAs(anotherPending)
}

@Test
fun testAsyncResultSubject_pendingResult_checkHasDifferentEffectiveValue() {
val successResult: AsyncResult<String> = AsyncResult.Success("Some string")
AsyncResultSubject.assertThat(pendingResult)
.hasSameEffectiveValueAs(successResult)
.isFalse()
}

@Test
fun testAsyncResultSubject_isComparableSuccessThat_checkIntValue() {
val intResult: AsyncResult<Int> = AsyncResult.Success(100)
AsyncResultSubject.assertThat(intResult)
.isComparableSuccessThat<Int>()
.isEqualTo(100)
}

@Test
fun testAsyncResultSubject_successResult_checkStringSuccessValue() {
AsyncResultSubject.assertThat(successResult)
.isSuccessThat()
.isEqualTo("Some string")
}

@Test
fun testAsyncResultSubject_failureResult_checkErrorMessageMatchesExact() {
AsyncResultSubject.assertThat(failureResult)
.isFailureThat()
.hasMessageThat()
.isEqualTo("Error message")
}

@Test
fun testAsyncResultSubject_pendingResult_checkHasNullEffectiveValue() {
val nullPending: AsyncResult<String> = AsyncResult.Pending()
AsyncResultSubject.assertThat(pendingResult)
.hasSameEffectiveValueAs(nullPending)
.isTrue()
}

@Test
fun testAsyncResultSubject_pendingResult_checkIsNotSameEffectiveValue() {
val pending1: AsyncResult<String> = AsyncResult.Pending()
val pending2: AsyncResult<String> = AsyncResult.Pending()
AsyncResultSubject.assertThat(pending1)
.hasSameEffectiveValueAs(pending2)
.isTrue()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,20 @@ oppia_android_test(
"//utility/src/main/java/org/oppia/android/util/networking:debug_module",
],
)

oppia_android_test(
name = "AsyncResultSubjectTest",
srcs = ["AsyncResultSubjectTest.kt"],
custom_package = "org.oppia.android.testing.data",
test_class = "org.oppia.android.testing.data.AsyncResultSubjectTest",
test_manifest = "//testing:test_manifest",
deps = [
"//testing/src/main/java/org/oppia/android/testing/data:async_result_subject",
"//testing/src/main/java/org/oppia/android/testing/robolectric:test_module",
"//third_party:androidx_test_ext_junit",
"//third_party:com_google_truth_truth",
"//third_party:junit_junit",
"//third_party:org_robolectric_robolectric",
"//third_party:robolectric_android-all",
],
)
Loading