Попытка ввести макеты в упражнение, используя кинжал, чтобы заглушить в модульном тесте - PullRequest
0 голосов
/ 03 мая 2019
android studio 3.4
dagger-android 2.19

Я пытаюсь проверить свою активность, и я хочу внедрить макеты в активность из модульного теста с помощью кинжала.

У меня есть простой ForecastActivity

class ForecastActivity : AppCompatActivity() {

    @Inject
    lateinit var locationUtils: LocationUtils

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)

        if(locationUtils.isLocationServicesEnabled(this)) {
            locationUtils.getLocationCoordinates(this)
        }
        else {
            startRetryFragment()
        }
    }
}

Проблема в том, что я хочу внедрить макет LocationUtils.

У меня есть модуль кинжала, который возвращает макет для моего юнит-тестирования:

@Module
class ActivityTestModule {
    @Reusable
    @Provides
    fun provideLocationUtils(): LocationUtils = mock()
}

И компонент:

@Singleton
@Component(modules = [ActivityTestModule::class])
interface TestComponent {
    fun inject(forecastActivityTest: ForecastActivityTest)
}

У меня есть класс тестового приложения, который расширяет ForecastApplication

class TestApplication : ForecastApplication() {

    private lateinit var testComponent: TestComponent

    override fun onCreate() {
        super.onCreate()

        testComponent = DaggerTestComponent
            .builder()
            .build()
    }

    fun getTestComponent() = testComponent
}

Для реального модульного теста у меня есть следующее, но есть много ошибок, и код не работает.Я сделал комментарий, где я думаю, что проблемы:

@RunWith(AndroidJUnit4::class)
class ForecastActivityTest {
    private lateinit var forecastActivityScenario: ActivityScenario<ForecastActivity>

    @Inject
    lateinit var locationUtils: LocationUtils

    @Before
    fun setUp() {
        /* Cast error that cannot be cast to a ForecastApplication */
        val testApplication = getApplicationContext<ForecastApplication>() as TestApplication

        testApplication.getTestComponent()
            .inject(this)

        forecastActivityScenario = ActivityScenario.launch(ForecastActivity::class.java)

        /* Want to stub this locationUtils, as the real implementation passes in instance of the ForecastActivity I don't think will work. Just wondering is it better to use `any()` instead for `isLocationServiceEnabled(any())` */
        whenever(locationUtils.isLocationServicesEnabled(any())).thenReturn(true)

        forecastActivityScenario.moveToState(Lifecycle.State.DESTROYED)

        assertThat(locationUtils).isNotNull
    }

    @Test
    fun `forecastActivityScenario should not be null`() {
        assertThat(forecastActivityScenario).isNotNull

        forecastActivityScenario = ActivityScenario.launch(ForecastActivity::class.java)
        forecastActivityScenario.moveToState(Lifecycle.State.CREATED)
    }
}

Я также изменил настройку, чтобы попытаться заставить это работать, используя следующее.Однако фиктивный LocationUtils создается в ForecastActivityTest, но в кинжале ForecastActivity вводится реальная реализация, а не имитатор, который был в модульном тесте, поэтому whenever(locationUtils.isLocationServicesEnabled(any())).thenReturn(true) работает.

@Before
fun setUp() {
    DaggerTestComponent
        .builder()
        .build()
        .inject(this)

    forecastActivityScenario = ActivityScenario.launch(ForecastActivity::class.java)
    whenever(locationUtils.isLocationServicesEnabled(any())).thenReturn(true)
    forecastActivityScenario.moveToState(Lifecycle.State.DESTROYED)
    assertThat(locationUtils).isNotNull
}

Большое спасибозаранее,

Я только показал реализацию кинжала со стороны модульного тестирования.В противном случае вопрос будет слишком длинным

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...