Предоставлять насмешливый объект другому конструктору конструктивного объекта?

Первоначальное модульное тестирование и использование Mockito. Я не уверен, думаю ли я об этом правильно. Вот ситуация:

В моем приложении для Android я использую Model-View-Presenter. Я пытаюсь проверить метод в моем классе презентатора под названием validateCredential(serviceManager: ServiceManager, email: String, password: String) чтобы узнать, будет ли диспетчер службы, который я передаю ему, в конечном итоге вызвать обратный вызов (этот метод вызывается видом) путем проверки его с помощью mockito.

 // method in presenter class override fun validateCredential(serviceManager: ServiceManager, email: String, password: String) { loginModel = LoginModel(email, password) serviceManager.getParent(email, password) serviceManager.execute() } // callback implemented by presenter class private fun handleLoginResult(result: ServiceManager.RequestResult, data: ByteArray, responseCode: Int, optionalParam: String) { ... mView.startHomeScreen() } 

Класс презентатора также реализует интерфейс обратного вызова ( IServiceAsyncTaskCallback ), который предоставляется конструктору IServiceAsyncTaskCallback . В этом конкретном модульном тесте я хочу убедиться, что mView.startHomeScreen() .

Проблема:

  • Тестирование модулей Android, по-видимому, требует, чтобы ServiceManager был посмеян (ServiceManager расширяет абстрактный класс AsyncTask), потому что, когда я вызываю execute() , тестовая библиотека Android будет вызывать исключение, если оно не издевается.
  • Однако, если я высмеиваю ServiceManager, я не могу предоставить ему два необходимых параметра конструктору, который ДОЛЖЕН быть издеваемым, если я правильно разбираюсь в модульном тестировании. Два параметра для конструктора – это обратный вызов интерфейса (который является классом презентатора) и объект класса, который отвечает за отправку JSON через http. Оба они должны издеваться, правильно? Потому что в модульном тесте вы не хотите, чтобы эти зависимости действительно выполняли HTTP-вызовы или вызывали обратные вызовы, правильно?
  • Кажется, я переусердствовал. То, что я действительно хочу, – это увидеть, был ли мой объект представления передан ведущему, вызывает startHomeScreen() , поэтому я должен просто забыть проверить validateCredentialMethod() и просто вызвать handleLoginResult(...) напрямую. Это лучше, чем выше маршрут?
  • Однако другая проблема заключается в том, что даже если я вызываю handleLoginResult(...) непосредственно, чтобы проверить, handleLoginResult(...) ли mock-представление, переданное ведущему, этот код метода содержит вызов JSONObject, который является кодом, связанным с Android, и поскольку он принадлежит файл android.jar, он выкинет исключение, потому что это не издевается! Должен ли я обеспечить инъекцию для этого тоже ?!

Я потерялся, как проверить это. Каков правильный способ проверить, что startHomeScreen() ?

Проблема в том, что вы пытаетесь протестировать два отдельных класса в одном модульном тесте, что делает его не модульным тестом.

С вашей текущей настройкой кажется, что вы хотите иметь 3 разных тестовых примера в двух разных классах (составляя имена, пытаясь быть максимально ясными относительно своего контента):

  • PresenterTest

    • testThatServiceManagerIsExcecutedOnValidateCredential
    • testThatStartHomeScreenIsCalledWhenHandlingLoginResult
  • ServiceManagerTest

    • testCallbackIsCalledOnExcecuted