Thanks to visit codestin.com
Credit goes to github.com

Skip to content

2.3.1 fails to mock certain classes that 2.3.0 successfully mocks #367

@sglowery

Description

@sglowery

I have a Kotlin project that utilizes the kotlin-telegram-bot library, and I use Groovy and Spock for my tests. In my tests, I mock out the various data classes used in the kotlin-telegram-bot library such as Message, Chat and User, and because classes in Kotlin are final by default, spock-mockable makes things so much easier to test. With spock-mockable 2.3.0, all my tests pass, but when updating to 2.3.1, all of the tests that mock those data classes fail. Here's my build.gradle.kts (using Gradle 7.4.2, if that information is useful):

plugins {
    kotlin("jvm") version "1.8.20"
    groovy
}

repositories {
    mavenCentral()
    maven(url = "https://jitpack.io")
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("io.github.kotlin-telegram-bot.kotlin-telegram-bot:telegram:6.0.7")
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
    testImplementation("org.spockframework.spock:spock-core:spock-2.3")
    testImplementation("org.jetbrains.kotlin:kotlin-test")
    testImplementation("org.objenesis:objenesis:3.3")
    testImplementation("io.github.joke:spock-mockable:2.3.0")
}

tasks.test {
    useJUnitPlatform()
    jvmArgs?.add("-javaagent:${classpath.find { it.name.contains("spock-mockable") }?.absolutePath}")
}

kotlin {
    jvmToolchain(17)
}

One such test that runs in 2.3.0 but fails in 2.3.1 looks like this:

    def "execute returns PrivateChat if command is sent from a private chat"() {
        given:
        def message = Mock(Message) {
            getChat() >> Mock(Chat) {
                getType() >> "private"
            }
        }

        expect:
        PrivateChat.INSTANCE == StartGameCommandHandler.INSTANCE.execute(message)
    }

The only difference between this test passing and failing is the version of spock-mockable, and it fails with this stack trace:

Cannot create mock for class com.github.kotlintelegrambot.entities.Message  because Java mocks cannot mock final classes. If the code under test is written in Groovy, use a Groovy mock.
org.spockframework.mock.CannotCreateMockException: Cannot create mock for class com.github.kotlintelegrambot.entities.Message  because Java mocks cannot mock final classes. If the code under test is written in Groovy, use a Groovy mock.
	at org.spockframework.mock.runtime.JavaMockFactory.createInternal(JavaMockFactory.java:48)
	at org.spockframework.mock.runtime.JavaMockFactory.create(JavaMockFactory.java:38)
	at org.spockframework.mock.runtime.CompositeMockFactory.create(CompositeMockFactory.java:44)
	at org.spockframework.lang.SpecInternals.createMock(SpecInternals.java:50)
	at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:305)
	at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:295)
	at org.spockframework.lang.SpecInternals.MockImpl(SpecInternals.java:108)
	at xyz.abc.project.telegram.handlers.startgame.StartGameCommandHandlerTest.execute returns PrivateChat if command is sent from a private chat(StartGameCommandHandlerTest.groovy:17)

The kotlin-telegram-bot library is written in Kotlin (obviously) so using a regular Mock should be fine, but I did try using GroovyMock anyway to see if it works and it doesn't.

Let me know if there's any other information I can add.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions