【问题标题】:JUnit 5 Annotations - Not Working with LiveData / Parameterized TestsJUnit 5 注释 - 不使用 LiveData / 参数化测试
【发布时间】:2019-10-17 08:14:05
【问题描述】:

概述

预期行为

将使用 mockObject 函数 implementation 的模拟对象初始化替换为 documentation 和 Medium post 中所述的 JUnit 5 的注释语法初始化 @oleksiyp。

当前行为

有问题的测试是@phauer 为 JUnit 5 概述的 parameterized test,它似乎与 @ExtendWith(MockKExtension::class) 冲突。为了使用 LiveData 实现测试,测试必须使用 @JeroenMols 设计的 InstantExecutorExtension 在本地单元测试中同步运行。

模拟对象初始化使用mockObject 函数按预期工作,但使用注释@MockK 失败。

错误

警告消息/构建失败:

尚不支持具有非 SOURCE 保留的可重复注释。

实施

mockObject 函数实现(按预期工作)

@ExtendWith(InstantExecutorExtension::class)
class NavigateContentTests {
    private val mainThreadSurrogate = newSingleThreadContext("UI thread")
    private val contentViewModel = ContentViewModel()

    // This is the stream of tests to run in the Parameterized test below.
    private fun NavigateContent() = Stream.of(
            NavigateContentTest(
                    isRealtime = false,
                    feedType = MAIN,
                    timeframe = DAY,
                    mockFeedList = mockDbContentListForDay,
                    mockContent = mockArticleContent),
            ...)

    @BeforeAll
    fun beforeAll() { mockkObject(ContentRepository) }

    @AfterAll
    fun afterAll() { unmockkAll() // Re-assigns transformation of object to original state prior to mock. }

    @BeforeEach
    fun beforeEach() { Dispatchers.setMain(mainThreadSurrogate) }

    @AfterEach
    fun afterEach() {
        Dispatchers.resetMain() // Reset main dispatcher to the original Main dispatcher.
        mainThreadSurrogate.close()
    }

    @ParameterizedTest
    @MethodSource("NavigateContent")
    fun `Navigate Content`(test: NavigateContentTest) = runBlocking {
        every { ContentRepository.getMainFeedList(test.isRealtime, any()) } returns mockGetMainFeedList(
                test.mockFeedList, CONTENT)
        every {
            ContentRepository.queryLabeledContentList(test.feedType)
        } returns mockQueryMainContentList(test.mockFeedList)
        every { ContentRepository.getContent(test.mockContent.id) } returns mockGetContent(test)
        // Tests here...
        // Verification here...
    }
}

注解语法初始化(由于两个扩展 @ExtendWith 而不起作用)

@ExtendWith(InstantExecutorExtension::class)
@ExtendWith(MockKExtension::class)
class NavigateContentTests {

    // This object should be mocked.
    @MockK
    lateinit var contentRepository: ContentRepository

    private val mainThreadSurrogate = newSingleThreadContext("UI thread")
    private val contentViewModel = ContentViewModel()

    // This is the stream of tests to run in the Parameterized test below.
    private fun NavigateContent() = Stream.of(
            NavigateContentTest(
                    isRealtime = false,
                    feedType = MAIN,
                    timeframe = DAY,
                    mockFeedList = mockDbContentListForDay,
                    mockContent = mockArticleContent),
            ...)

    @BeforeAll
    fun beforeAll() {  MockKAnnotations.init(this, relaxUnitFun = true) // turn relaxUnitFun on for }

    @AfterAll
    fun afterAll() { unmockkAll() // Re-assigns transformation of object to original state prior to mock. }

    @BeforeEach
    fun beforeEach() { Dispatchers.setMain(mainThreadSurrogate) }

    @AfterEach
    fun afterEach() {
        Dispatchers.resetMain() // Reset main dispatcher to the original Main dispatcher.
        mainThreadSurrogate.close()
    }

    @ParameterizedTest
    @MethodSource("NavigateContent")
    fun `Navigate Content`(test: NavigateContentTest) = runBlocking {
        every { contentRepository.getMainFeedList(test.isRealtime, any()) } returns mockGetMainFeedList(
                test.mockFeedList, CONTENT)
        every {
            contentRepository.queryLabeledContentList(test.feedType)
        } returns mockQueryMainContentList(test.mockFeedList)
        every { contentRepository.getContent(test.mockContent.id) } returns mockGetContent(test)
        // Tests here...
        // Verification here...
    }
}

环境

  • MockK 版本:1.9.3
  • 操作系统:Mac 10.14.6
  • Kotlin 版本:1.3.50
  • JDK 版本:12.0.1
  • JUnit 版本:5.5.1
  • 测试类型:单元测试

【问题讨论】:

  • 尝试将@ExtendsWith.. @ExtendWith(InstantExecutorExtension::class) @ExtendWith(MockKExtension::class) 组合成组合方式:@ExtendWith({InstantExecutorExtension::class, MockKExtension::类})

标签: android kotlin android-testing junit5 mockk


【解决方案1】:

这是根据 GitHub issue 的一个错误,由 MockK 创建者 @oleksiy 记录。

我会在看到问题解决后更新这篇文章。

【讨论】:

    猜你喜欢
    • 2015-03-13
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 2022-10-06
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多