Android Интеграционный тест: моделирование логики / метода в деятельности с помощью Dagger и Mockito и получение возвращенного значения в тесте - PullRequest
0 голосов
/ 15 февраля 2020

Я разрабатываю приложение Android с использованием Kotlin. Я также пишу интегрированные тесты для моего приложения, используя Dagger и Expresso. У меня сейчас проблема с издевательством над логи c. Во-первых, позвольте мне показать вам, как я высмеиваю logi c в коде, используя Dagger для интегрированных тестов.

У меня есть класс компонента приложения Dagger для теста со следующим определением

@Singleton
@Component(modules = [ TestAppModule::class ])
interface TestAppComponent : AppComponent //App component is the actual class used for the application
{
    fun inject(app: MainActivity)
}

Это определение класса TestAppModule

@Module
open class TestAppModule (private val app: Application) {
    @Singleton
    @Provides
    open fun fileIOService(): IFileIOService {
        return FakeFileIOService()
    }
}

У меня также есть класс AppModule для фактического кода приложения со следующим определением.

@Module
open class TestAppModule (private val app: Application) {
    @Singleton
    @Provides
    open fun fileIOService(): IFileIOService {
        return FakeFileIOService()
    }
}

Идея состоит в том, что Интеграционные тесты будут использовать TestAppModule, поэтому будет добавлен класс FakeFileIOService. Для реального приложения оно будет использовать AppModule, поэтому вместо него будет введен класс FileIOService. Класс FakeFileIOService и класс FileIOService наследуются от интерфейса IFileIOService. Интерфейс IFileIOService будет иметь следующее определение:

interface IFileIOService
{
    fun saveFile(data: String)
}

Класс FileIOService и класс FakeIOService будут иметь свою собственную версию реализации для метода saveFile. FakeIOService будет иметь фиктивную версию.

У меня будет свойство IFileIOService в классе MainActivity для внедрения зависимостей.

class MainActivity: AppCompatActivity()
{
    @Inject
    lateinit var fileIOService: IFileIOService
}

Как я уже говорил, класс FakeFileIOService будет внедрен для интеграционные тесты. Код работает отлично. Он использует поддельную версию для интеграционных тестов и конкретную версию для реального применения.

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

Но теперь у меня проблема с проверкой логики c с использованием Mokito для тестирования File и возвращением поддельного значения обратно в тестах.

Ниже приведена реализация моего

fun saveFile(data: String) {
    FileOutputStream mockFos = Mockito.mock(FileOutputStream.class);
    mockFos.write(data.getBytes());
    mockFos.close();
}

Буквально я пытаюсь чтобы смоделировать файл logi c с помощью Mockito. Затем я пытаюсь написать интеграционный тест примерно так.

@get:Rule
var mainActivityRule: ActivityTestRule<MainActivity> = ActivityTestRule<MainActivity>(CameraActivity::class.java, true, false)

@Test
fun fileIsSaveInWhenButtonIsClicked() {
    Intents.init()
    var targetContext: Context = InstrumentationRegistry.getInstrumentation().targetContext
    var intent: Intent = Intent(targetContext, MainActivity::class.java)
    this.mainActivityRule.launchActivity(null) 
    onView(withId(R.id.button_save_file)).perform(click())

    //here I want to assert if the file is saved using Mockito something like this
    //verify(mockFos).write(data.getBytes()); the issue is that I cannot get the mockFos instance creatd in the saveFile method of the FakeFileIOService class
    Intents.release()
}

См. Комментарий в тесте. Проблема в том, что я хочу проверить, сохранен ли файл с помощью Mockito. Но проблема в том, что я не могу получить экземпляр mockFos, созданный в saveFile класса FakeIOService. Как я могу проверить это? Как лучше всего проверить этот сценарий?

1 Ответ

1 голос
/ 15 февраля 2020

Вы не должны издеваться над системными логами c. Запись в файл и закрытие файла - это системные логики c. Предполагается, что вы только издеваетесь над своей собственной логикой c.

И вы должны проверить, что был вызван метод saveFile. Не то чтобы содержимое saveMyFile было вызвано.

val mock = mock(IFileIOService::class.java)
mainActivity.fileIOService = mock

//do something that in return does fileIOService.saveFile

verify(mock).saveFile(any())

Другой вариант - шпионить:

 val spy = spy(mainActivity.fileIOService)
 //do something that in return does fileIOService.saveFile

 verify(spy).saveFile(any())
...