Как вы поступаете с NavController, когда действия переключаются во время тестирования? - PullRequest
0 голосов
/ 21 июня 2020

В настоящее время я работаю над проектом Android Studio и сейчас проверяю, переключается ли LoginActivity на MainActivity после правильного входа в систему.

Вот код LoginActivity.kt:

    24 class LoginActivity : AppCompatActivity() {
    26    override fun onCreate(savedInstanceState: Bundle?) {
    27    super.onCreate(savedInstanceState)

    29    setContentView(R.layout.activity_login)

    31    val username = findViewById<EditText>(R.id.username)
    32    val password = findViewById<EditText>(R.id.password)
    33    val login = findViewById<Button>(R.id.login)
    34    val loading = findViewById<ProgressBar>(R.id.loading)
    35    val errortext = findViewById<TextView>(R.id.errortext)
    36    val registerbutton = findViewById<Button>(R.id.registerbutton)
    37    val loginViewModel : LoginViewModel by viewModel()

    39    loginViewModel.loginFormState.observe(this@LoginActivity, Observer {
    40        val loginState = it ?: return@Observer

    42        // disable login button unless both username / password is valid
    43        login.isEnabled = loginState.isDataValid

    45        if (loginState.usernameError != null) {
    46            username.error = getString(loginState.usernameError)
    47        }
    48        if (loginState.passwordError != null) {
    49            password.error = getString(loginState.passwordError)
    50        }
    51    })

    53    loginViewModel.loginResult.observe(this@LoginActivity, Observer {
    54        val loginResult = it ?: return@Observer
    55        loading.visibility = View.GONE
    56        if (loginResult.error != null) {
    57            errortext.visibility = View.VISIBLE
    58            errortext.text = loginResult.error.message
    59        }
    60        if (loginResult.success != null) {
    61            val sharedPreferences = this.getSharedPreferences("user", Context.MODE_PRIVATE)
    62            val mEditor = sharedPreferences.edit()
    63            mEditor.putString("currentUser", loginResult.success.jwtToken)
    64            mEditor.apply()
    65            val intent = Intent(this, MainActivity::class.java)
    66            intent.putExtra("hi", "HI")
    67            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    68            startActivity(intent)
    69            //Complete and destroy login activity once successful
    70            setResult(Activity.RESULT_OK)
    71            finish()
    72        }
    73    })

    75    username.afterTextChanged {
    76        loginViewModel.loginDataChanged(
    77            username.text.toString(),
    78            password.text.toString()
    79        )
    80    }

    82    password.apply {
    83        afterTextChanged {
    84            loginViewModel.loginDataChanged(
    85                username.text.toString(),
    86                password.text.toString()
    87            )
    88        }

    90        setOnEditorActionListener { _, actionId, _ ->
    91            when (actionId) {
    92                EditorInfo.IME_ACTION_DONE ->
    93                    loginViewModel.login(
    94                        username.text.toString(),
    95                        password.text.toString()
    96                    )
    97            }
    98            false
    99        }

    101        login.setOnClickListener {
    102            loading.visibility = View.VISIBLE
    103            loginViewModel.login(username.text.toString(), password.text.toString())
    104        }

    106        registerbutton.setOnClickListener{
    107            val intent = Intent(this.context, RegisterActivity::class.java)
    108            intent.putExtra("hi", "HI")
    109            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    110            startActivity(intent)
    111            finish()
    112        }
    113    }
    114  }
    115}

Вот код MainActivity.kt:

    18 class MainActivity : AppCompatActivity() {

    20 private lateinit var drawerLayout : DrawerLayout
    21 private lateinit var username: String
    22 @RequiresApi(Build.VERSION_CODES.O)
    23 override fun onCreate(savedInstanceState: Bundle?) {
    24    super.onCreate(savedInstanceState)
    25    val sharedPreferences = this.getSharedPreferences("user", Context.MODE_PRIVATE)
    26    if(sharedPreferences.contains("currentUser")) {
    27        val key = sharedPreferences.getString("currentUser", "")
    28        val expiration = JwtUtils.getExpiracyDate(key ?: "")
    29        val mEditor = sharedPreferences.edit()
    30        if (expiration.before(Date())) {
    31            mEditor.remove("currentUser")
    32            mEditor.apply()
    33            startLogin()
    34        }
    35        username = JwtUtils.getUsername(key ?: "")
    36    }
    37    else{
    38        startLogin()
    39    }
    40    val navController = this.findNavController(R.id.menuFragment)
    41    val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
    42    drawerLayout = binding.drawerLayout
    43    NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
    44    NavigationUI.setupWithNavController(binding.rulechecklist, navController)
    45}

    47fun startLogin(){
    48    val intent = Intent(this, LoginActivity::class.java)
    49    intent.putExtra("hi", "HI")
    50    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    51    startActivity(intent)
    52}

    54override fun onSupportNavigateUp(): Boolean {
    55    val navController = this.findNavController(R.id.fragment_register)
    56    return NavigationUI.navigateUp(navController, drawerLayout)
    57}
    58}

Вот код теста Android Studio, который выдает ошибку:

    29 @RunWith(AndroidJUnit4::class)
    30 @LargeTest
    31 class LoginActivityTest : KoinTest{
    37 @Test
    38 fun LoginActivity_login_CorrectParameters_SwitchesScreens(){
    39    stopKoin()
    40    startKoin{modules(fakeUserModule)}
    41    val scenario = launchActivity<LoginActivity>()
    42    scenario.moveToState(Lifecycle.State.RESUMED)
    43    onView(withId(R.id.username)).perform(replaceText("Nedl"))
    44    onView(withId(R.id.password)).perform(replaceText("Globoesporte"))
    45    onView(withId(R.id.login)).perform(click())
    46    assertThat(Activity.RESULT_OK, `is`(scenario.result.resultCode))
    47}
    70}

В настоящее время когда я запускаю тест, это ошибка консоли:

java.lang.IllegalArgumentException: ID does not reference a View inside this Activity
at android.app.Activity.requireViewById(Activity.java:2678)
at androidx.core.app.ActivityCompat.requireViewById(ActivityCompat.java:363)
at androidx.navigation.Navigation.findNavController(Navigation.java:58)
at androidx.navigation.ActivityKt.findNavController(Activity.kt:30)
at com.example.starsign.MainActivity.onCreate(MainActivity.kt:40)
at android.app.Activity.performCreate(Activity.java:7136)
at android.app.Activity.performCreate(Activity.java:7127)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at androidx.test.runner.MonitoringInstrumentation.callActivityOnCreate(MonitoringInstrumentation.java:711)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at androidx.test.espresso.base.Interrogator.loopAndInterrogate(Interrogator.java:148)
at androidx.test.espresso.base.UiControllerImpl.loopUntil(UiControllerImpl.java:525)
at androidx.test.espresso.base.UiControllerImpl.loopUntil(UiControllerImpl.java:484)
at androidx.test.espresso.base.UiControllerImpl.injectMotionEvent(UiControllerImpl.java:236)
at androidx.test.espresso.action.MotionEvents.sendUp(MotionEvents.java:162)
at androidx.test.espresso.action.MotionEvents.sendUp(MotionEvents.java:139)
at androidx.test.espresso.action.Tap.sendSingleTap(Tap.java:170)
at androidx.test.espresso.action.Tap.access$100(Tap.java:31)
at androidx.test.espresso.action.Tap$1.sendTap(Tap.java:47)
at androidx.test.espresso.action.GeneralClickAction.perform(GeneralClickAction.java:137)
at androidx.test.espresso.ViewInteraction$SingleExecutionViewAction.perform(ViewInteraction.java:366)
at androidx.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:255)
at androidx.test.espresso.ViewInteraction.access$100(ViewInteraction.java:65)
at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:158)
at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:155)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Шестая строка сообщения об ошибке указывает, что ошибка связана с тем, что NavController не вводится должным образом в MainActivity. Однако, поскольку тестирование выполняется в LoginActivity, а MainActivity запускается только при нажатии кнопки входа в систему, возникает вопрос, как я могу ввести фиктивный NavController в MainActivity в момент вызова MainActivity. Кто-нибудь может мне помочь?

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