“runTest does not run on main thread” 的中文翻译是:”runTest 不在主线程上运行”。

huangapple go评论63阅读模式
英文:

runTest does not run on main thread

问题

我正在编写一个测试,并从标准库中收到以下错误信息:

java.lang.IllegalStateException: Method addObserver must be called on the main thread

这是我的简化测试方法:

@Test
fun useAppContext() = runTest {
assert(isMainThread())
}

我如何使这个测试成功?我需要在我的测试中的某个地方添加一个观察者,但因为我需要在主线程上这样做,所以测试失败。

英文:

I am writing a test and I get this error from a standard library:

java.lang.IllegalStateException: Method addObserver must be called on the main thread

This is my simplified test method:

@Test
fun useAppContext() = runTest {
    assert(isMainThread())
}

How can I make this test succeed? I need to add an observer somewhere in my test which fails because I need to do so on the main thread.

答案1

得分: 3

代码部分不需要翻译,以下是翻译好的内容:

runBlocking一样(以及直接在@Test方法中编写的代码一样),runTest中的代码默认在测试线程上运行,而不是在主线程上运行。这通常是您想要的行为,因为如果不让出主线程,它将不会运行布局,您的UI将完全冻结。

在UI线程上运行测试的特定部分

如果您只有测试的特定部分应在UI线程上运行,例如您的addObserver调用示例,您可以为测试的该部分切换协程调度器。

withContext(Dispatchers.Main)包围方法的相关部分

@Test
fun someTestMethod() = runTest {
    withContext(Dispatchers.Main) {
        assert(isMainThread())
    }
}

在UI线程上运行整个测试

如果您确实希望在主线程上运行测试(例如,因为它是一个不涉及任何布局的简单测试,或者因为您想手动控制何时使用suspend方法(例如Compose的withFrameNanos)让出主线程),可以使用@UiThreadTest注释来实现。

@UiThreadTest注释测试方法(或者如果所有@Test@Before@After方法都应在UI线程上运行,则注释类)。

@Test
@UiThreadTest
fun someTestMethod() = runTest {
    assert(isMainThread())
}
英文:

Like runBlocking (and like code written directly in @Test methods), code within runTest is run on the test thread by default, rather than on the main thread. This is usually the behavior you want, because if you don't yield the main thread, it will not run layouts, and your UI will be completely frozen.

To run a specific part of your test on the UI thread

If you just have a specific part of your test that should be run on the UI thread, such as your example of the addObserver call, you can switch the coroutine dispatcher for that specific part of the test.

Surround the relevant part of your method with withContext(Dispatchers.Main)

@Test
fun someTestMethod() = runTest {
    withContext(Dispatchers.Main) {
        assert(isMainThread())
    }
}

To run your entire test on the UI thread

If you do want to run your test on the main thread (for example, because it's a simple test that doesn't involve any layouts, or because you want to manually control when you yield the main thread with suspend methods (such as Compose's withFrameNanos), this can be done with the @UiThreadTest annotation.

Annotate the test method (or the class, if all @Test, @Before, and @After methods should be run on the UI thread) with @UiThreadTest.

@Test
@UiThreadTest
fun someTestMethod() = runTest {
    assert(isMainThread())
}

huangapple
  • 本文由 发表于 2023年4月19日 21:42:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76055265.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定