Mocking for Kotlin/Native and Kotlin Multiplatform using the Kotlin Symbol Processing API (KSP)

Overview

Mockative

Maven Central

Mocking for Kotlin/Native and Kotlin Multiplatform using the Kotlin Symbol Processing API (KSP).

Installation

Mockative uses KSP to generate mock classes for interfaces, and as such, it requires adding the KSP plugin in addition to adding the runtime library and symbol processor dependencies.

build.gradle.kts

plugins {
    id("com.google.devtools.ksp")
}

repositories {
    mavenCentral()
}

kotlin {
    sourceSets {
        val commonTest by getting {
            dependencies {
                implementation("io.mockative:mockative:1.0.0")
            }
        }
    }
}

dependencies {
    ksp(implementation("io.mockative:mockative-processor:1.0.0"))
}

Installation for JVM projects

build.gradle.kts

plugins {
    id("com.google.devtools.ksp")
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation("io.mockative:mockative-jvm:1.0.0")
    
    ksp(implementation("io.mockative:mockative-processor-jvm:1.0.0"))
}

Testing with Mockative

To mock a given method on an interface, annotate a property holding the interface type with the @Mock annotation, and assign it to the result of a call to the <T> mock(KClass<T>) function:

class GitHubServiceTests {
    @Mock
    val api = mock(GitHubAPI::class)
}

Then, to stub a function or property on the mock there is a couple of options:

Stubbing using Expressions

It is possible to stub a function or property by invoking it through the use of either the <R> invocation(T.() -> R) or <R> coroutine(T.() -> R) function available from the <T> given(T) function:

// Stub a `suspend` function
given(mock).coroutine { fetchData("mockative/mockative") }
    .then { data }

// Stub a blocking function
given(mock).invocation { transformData(data) }
    .then { transformedData }

// Stub a property getter
given(mock).invocation { mockProperty }
    .then { mockPropertyData }

// Stub a property setter
given(mock).invocation { mockProperty = transformedData }
    .thenDoNothing()

Stubbing using Callable References

Callable references allows you to match arguments on something other than equality:

// Stub a `suspend` function
given(mock).suspendFunction(mock::fetchData)
    .whenInvokedWith(oneOf("mockative/mockative", "mockative/mockative-processor"))
    .then { data }

// Stub a blocking function
given(mock).function(mock::transformData)
    .whenInvokedWith(any())
    .then { transformedData }

// Stub a property getter
given(mock).getter(mock::mockProperty)
    .whenInvoked()
    .then { mockPropertyData }

// Stub a property setter
given(mock).setter(mock::mockProperty)
    .whenInvokedWith(matching { it.name == "foo" })
    .thenDoNothing()

// When the function being stubbed has overloads with a different number of arguments, a specific
// overload can be selected using one of the `fun[0-9]` functions.
given(mock).function(mock::transformData, fun0())
    .whenInvokedWith(any())
    .then { transformedData }

// When the function being stubbed has overloads with the same number of arguments, but different
// types, the type arguments must be specified using one of the `fun[0-9]` functions.
given(mock).function(mock::transformData, fun2<Data, String>())
    .whenInvokedWith(any(), any())
    .then { transformedData }

// Additionally, you can stub functions and properties by their name, but in this case you'll
// need to provide type information for the matchers.
given(mock).function("transformData")
    .whenInvokedWith(any<Data>())
    .then { transformedData }

Stubbing implementations

Both expressions using given and callable references using when[...] supports the same API for stubbing the implementation, through the use of the then functions.

Function Description
then(block: (P1, P..., PN) -> R) Invokes the specified block. The arguments passed to the block are the arguments passed to the invocation.
thenInvoke(block: () -> R) Invokes the specified block.
thenReturn(value: R) Returns the specified value.
thenThrow(throwable: Throwable) Throws the specified exception.

When the return type of the function or property being stubbed is Unit, the following additional then function is available:

Function Description
thenDoNothing() Returns Unit.

The untyped callable references using <T : Any> whenInvoking(T, String) and <T : Any> whenSuspending(T, String) supports the following additional then function:

Function Description
then(block: (args: Array<Any?>) -> Any?) Invokes the specified block. The argument passed to the block is an array of arguments passed to the invocation.

Verification

Verification of invocations to mocks is supported through the verify(mock) API:

Verification using Expressions

// Expression (suspend function)
verify(mock).coroutine { fetchData("mockative/mockative") }
    .wasNotInvoked()

// Expression (blocking function)
verify(mock).invocation { transformData(data) }
    .wasInvoked(atLeast = 1.time)

// Expression (property getter)
verify(mock).invocation { mockProperty }
    .wasInvoked(atLeast = once, atMost = 6.times)

// Expression (property setter)
verify(mock).invocation { mockProperty = transformedData }
    .wasInvoked(exactly = 9.times)

Verification using Callable References

// Function Reference (suspend function)
verify(mock).coroutine(mock::fetchData)
    .with(eq("mockative/mockative"))
    .wasNotInvoked()

// Function Reference (blocking function)
verify(mock).function(mock::transformData)
    .with(any())
    .wasInvoked(atMost = 3.times)

// Getter
verify(mock).getter(mock::mockProperty)
    .wasInvoked(exactly = 4.times)

// Setter
verify(mock).setter(mock::mockProperty)
    .with(any())
    .wasInvoked(atLeast = 7.times)

Validation

// Verifies that all expectations were verified through a call to `verify(mock).wasInvoked()`.
verify(mock).hasNoUnverifiedExpectations()

// Verifies that the mock has no expectations that weren't invoked at least once.
verify(mock).hasNoUnmetExpectations()
Comments
  • Mocking not working

    Mocking not working

    I try to mock an expect/actual class that implements MultiDexApplication on Android.

    @Mock
    val application = mock(classOf<Application>())
    
    init {
         given(application).invocation { applicationContext }
             .thenReturn(ApplicationProvider.getApplicationContext())
    }
    

    When i try to run the code it says that no mock was generated but there is no more info about why and how to fix it.

    A mock for the type Application was not generated.
    
        Make sure the property holding the mock is annotated with @Mock:
    
            @Mock
            private val myMock = mock(classOf<Application>())
        
    
    io.mockative.NoSuchMockError: A mock for the type Application was not generated.
    
        Make sure the property holding the mock is annotated with @Mock:
    
            @Mock
            private val myMock = mock(classOf<Application>())
        
    
    	at app//io.mockative.MocksKt.mock(Mocks.kt:17)
    
    bug 
    opened by Nailik 10
  • Cannot mock function with generic type

    Cannot mock function with generic type

    Hello,

    I am trying to mock a function with generic type but I'm not certain if that is possible or how to do it exactly.

    Here is the function signature from the interface I'm trying to mock :

    suspend fun <T> getObject(input: GetObjectRequest, block: suspend (GetObjectResponse) -> T): T
    

    In my implementation, getObject<File> is being called.

    My failed attempt to mock it :

    given(s3Client).suspendFunction(s3Client::getObject, fun2<GetObjectRequest, suspend (GetObjectResponse) -> File>())
    		.whenInvokedWith(any(), any())
    		.then {
    			File("Dummy")
    		}
    

    Error :
    image
    None of the following functions can be called with the arguments supplied.

    opened by AlexandreBrown 8
  • Generic TypeAlias not handled correctly

    Generic TypeAlias not handled correctly

    Hi All

    First of all it's great to have a library that works multiplatform! Just a quick issue I found while playing around with things.

    Kotlin Version: 1.6.21 Mockative Version: 1.2.1

    Typealiases which contain a generic don't seem to be handled correctly. Minimal Example:

    typealias MyTypeAlias<T> = List<T>
    
    interface ToBeMocked {
        fun myFunction(): MyTypeAlias<Int>
    }
    
    class DemoTest() {
        @Mock
        private val myMock = mock(classOf<ToBeMocked>())
        @Test
        fun myTest() {
            // Fails before running
        }
    }
    

    Error:

    e: shared/build/generated/ksp/android/androidDebugUnitTest/kotlin/com/apadmi/kotlinmultiplatformtest/feature/pokemon/ToBeMockedMock.Mockative.kt: (12, 37): One type argument expected for typealias MyTypeAlias<T> = List<T>
    

    Generated Code:

    public class ToBeMockedMock : Mockable(stubsUnitByDefault = false), ToBeMocked {
      public override fun myFunction(): MyTypeAlias =
          invoke<MyTypeAlias>(Invocation.Function("myFunction", listOf<Any?>()), false)
    
      public override fun equals(other: Any?): Boolean = invoke<Boolean>(Invocation.Function("equals",
          listOf<Any?>(other)), false)
    
      public override fun hashCode(): Int = invoke<Int>(Invocation.Function("hashCode", listOf<Any?>()),
          false)
    
      public override fun toString(): String = invoke<String>(Invocation.Function("toString",
          listOf<Any?>()), false)
    }
    

    Hope this is helpful!

    opened by SamCosta1 8
  • Overriding Stubs

    Overriding Stubs

    In some use cases, developers need to override the previous stubs. Ie.

    I have a test method that I want my mock to return some value, and after I made my assertion I want it to return some other value

        @Test
        fun methodName() {
            given(settingsRepository)
                .getter(settingsRepository::adFreeEndDate)
                .whenInvoked()
                .thenReturn(nowAsLong())
                
            assert(...)
            verify(...)
    
            given(settingsRepository)
                .getter(settingsRepository::adFreeEndDate)
                .whenInvoked()
                .thenReturn(nowAsLong() + DAY)
    
            assert(...)
            verify(...)
        }
    

    Another use case, I have 11 test methods that I need to stub a mock, and only 2 of them to different values, since i can not override stubs, I have to have 11 times below:

         @Test
        fun methodName() {
            given(...)
            
            // rets of the implementation
        }
    

    But if I am able to override the stubs, I could have this:

        @BeforeTest
        fun setup() {
            given(...)
        }
    

    And only for 2 test methods this:

         @Test
        fun methodName() {
            given(...)
            
            // rets of the implementation
        }
    

    So that the value stubbed in @BeforeTest will be overrided

    opened by mustafaozhan 6
  • Gradle error when installing mockative processor

    Gradle error when installing mockative processor

    I'm trying to install mockative to a KMM iOS/Android project, but running into the following issue:

    Type mismatch: inferred type is Dependency? but Any was expected
    

    Below is the gist of my build.gradle:

    plugins {
        kotlin("multiplatform")
        kotlin("plugin.serialization") version "1.5.31"
        id("com.android.library")
        id("kotlin-android-extensions")
        id("com.google.devtools.ksp") version "1.5.31-1.0.0"
    }
    
    kotlin {
        sourceSets {
            val commonTest by getting {
                dependencies {
                    implementation("io.mockative:mockative:1.0.6")
                }
            }
        }
    }
    
    dependencies {
        ksp(implementation("io.mockative:mockative-processor:1.0.6"))
    }
    

    However it's failing on the mockative-processor step

    opened by Janglinator 5
  • Support ir (#1)

    Support ir (#1)

    Many projects have moved on to using the IR compiler. In my case, specifically, turbine 0.9.0 and all future releases do not support the legacy JS:

    Support for legacy JS has been removed. Only JS IR is now supported.

    This mocking library looks very promising, but my projects have also moved on from legacy JS as well. Thus, either this framework must support IR JS, or it is not an option for me.

    In this PR I . . .

    • upgraded Kotlin: 1.6.20 -> 1.7.20
    • upgraded symbol-processing-api: 1.6.20-1.0.5 -> 1.7.20-1.0.8
    • specified js target to use IR.

    I also bumped the patch version, but I don't know if this is what is desired from the person making the pull request. Please make any changes or suggest any changes necessary.

    For my part, I've tested that basic mocking and verification features work on JVM and JS. However, I have not done as thorough testing as may be necessary to say that other changes are not required or that I haven't broken something.

    opened by ryansgot 4
  • Trying to use the library results in `A mock for the type X was not generated` error.

    Trying to use the library results in `A mock for the type X was not generated` error.

    Hello,

    I'm trying to use the library to test some shared kotlin multiplatform code, and I keep having the A mock for the type X was not generated error.

    I think that the problem is, if I want to mock class A(val xxx: X) {}, (with @Mock private val a = mock(classOf<A>())) I need to mock X too.

    Is this right ?

    In my case, X is another library's class, that itself uses other classes.

    Is there a simple way to handle this ?

    Thanks.

    opened by aminecmi 4
  • Generate toString, hashCode and equals method for every mock

    Generate toString, hashCode and equals method for every mock

    Hi there,

    is it possible to generate toString, hashCode and equals method for every mock? I also think, that they shouldn't be part of verification. As it is missing now, it generates a little problem - when you use mock in assertEquals, it fails. At first it gives error of missing expectation on toString() method call If you stub the toString(), there is another error - missing expectation on equals.

    I think that excluding those method from verification would lead to easier use of generated mocks.

    Example of currently failing code:

    @Mock
    private val createdMock = mock(classOf<IFaceToMock>())
    
    @Test
    fun test() {
      assertEquals(createdMock, createdMock)
    }
    

    thanks!

    opened by spartanmarty 4
  • Cannot use 'R' as reified type parameter. Use a class instead.

    Cannot use 'R' as reified type parameter. Use a class instead.

    Hello 👋

    I start using mockative for my KMP project and everything is going fine.

    Today, I get stuck with the following error

    e: /Users/runner/work/CCC/CCC/common/build/generated/ksp/iosTest/kotlin/com/github/mustafaozhan/ccc/common/db/sql/CurrencyQueriesMock.kt: (13, 216): Cannot use 'R' as reified type parameter. Use a class instead.
    e: /Users/runner/work/CCC/CCC/common/build/generated/ksp/iosTest/kotlin/com/github/mustafaozhan/ccc/common/db/sql/OfflineRatesQueriesMock.kt: (8, 216): Cannot use 'R' as reified type parameter. Use a class instead.
    

    I was trying to mock the Queries that is generated with sqldelight

    The relevant PR: Oztechan/CCC#354 You can find also the logs in GitHub checks

    bug 
    opened by mustafaozhan 4
  • Mutation attempt in new Coroutines

    Mutation attempt in new Coroutines

    I am trying to migrate to new coroutine memory model for my kotlin multiplatform project but the iOS target fails with following error:

    kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlin.collections.EmptySet@338bdd0
    kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlin.collections.EmptySet@338bdd0
    	at kotlin.Throwable#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt:24)
    	at kotlin.Exception#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:23)
    	at kotlin.RuntimeException#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:34)
    	at kotlin.native.concurrent.InvalidMutabilityException#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt:24)
    	at <global>.ThrowInvalidMutabilityException(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Internal.kt:109)
    	at <global>.Kotlin_AtomicReference_checkIfFrozen(Unknown Source)
    	at kotlin.native.concurrent.AtomicReference#<init>(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/concurrent/Atomics.kt:237)
    	at io.mockative.concurrency.AtomicReference#<init>(/Users/runner/work/mockative/mockative/mockative/src/nativeMain/kotlin/io/mockative/concurrency/AtomicReference.kt:7)
    	at io.mockative.concurrency.AtomicRef#<init>(/Users/runner/work/mockative/mockative/mockative/src/commonMain/kotlin/io/mockative/concurrency/Atomic.kt:6)
    	at io.mockative.concurrency.AtomicSet#<init>(/Users/runner/work/mockative/mockative/mockative/src/commonMain/kotlin/io/mockative/concurrency/AtomicSet.kt:8)
    	at io.mockative.Mockable#<init>(/Users/runner/work/mockative/mockative/mockative/src/commonMain/kotlin/io/mockative/Mockable.kt:13)
    	at com.oztechan.ccc.common.settings.SettingsRepositoryMock#<init>(/Users/mustafa.ozhan/Projects/Personal/CurrencyConverterCalculator/CCC/client/build/generated/ksp/ios/iosTest/kotlin/com/oztechan/ccc/common/settings/SettingsRepositoryMock.kt:19)
    	at io.mockative#mock(/Users/mustafa.ozhan/Projects/Personal/CurrencyConverterCalculator/CCC/client/build/generated/ksp/ios/iosTest/kotlin/io/mockative/GeneratedMocks.kt:4)
    	at com.oztechan.ccc.client.viewmodel.SettingsViewModelTest#<init>(/Users/mustafa.ozhan/Projects/Personal/CurrencyConverterCalculator/CCC/client/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/SettingsViewModelTest.kt:45)
    	at com.oztechan.ccc.client.viewmodel.$SettingsViewModelTest$test$0.createInstance#internal(/Users/mustafa.ozhan/Projects/Personal/CurrencyConverterCalculator/CCC/client/src/commonTest/kotlin/com/oztechan/ccc/client/viewmodel/SettingsViewModelTest.kt:41)
    	at kotlin.native.internal.test.BaseClassSuite.TestCase#run(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestSuite.kt:82)
    	at kotlin.native.internal.test.TestRunner.run#internal(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:245)
    	at kotlin.native.internal.test.TestRunner.runIteration#internal(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:271)
    	at kotlin.native.internal.test.TestRunner#run(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:286)
    	at kotlin.native.internal.test#testLauncherEntryPoint(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:30)
    	at kotlin.native.internal.test#main(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:34)
    	at <global>.Konan_start(/Users/teamcity1/teamcity_work/6326934d18cfe24e/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:33)
    	at <global>.Init_and_run_start(Unknown Source)
    	at <global>.start_sim(Unknown Source)
    	at <global>.0x0(Unknown Source)
    

    Related PR: https://github.com/Oztechan/CCC/pull/567

    bug 
    opened by mustafaozhan 3
  • The 'ksp' configuration is deprecated in Kotlin Multiplatform projects

    The 'ksp' configuration is deprecated in Kotlin Multiplatform projects

    I am getting the following warning when building my KMM project with mockative-processor dependency:

    The 'ksp' configuration is deprecated in Kotlin Multiplatform projects. Please use target-specific configurations like 'kspJvm' instead.

    Currently this doesn't seem to be causing any issues, but I'd like to get rid of it by switching to using the target-specific configurations. Any tips?

    opened by harmittaa 3
  • [Proposal] Support Library for mocking SQLDelight queries

    [Proposal] Support Library for mocking SQLDelight queries

    SQLDeligth is commonly used in Kotlin Multiplatform projects for state management. The generated queries can trivially be stubbed with Mockative given a few additional tools, which could be provided by a support library for mocking SQLDelight queries using Mockative, or as a non-mockative extension library. In particular, adding code like the following two classes will enable stubbing of SQLDelight generated queries using Mockative:

    class IteratorCursor<RowType : Any>(private val results: Iterator<RowType>) : SqlCursor {
        // Could also use AtomicRef from `kotlinx.atomicfu`
        private var _current: RowType? by AtomicReference(null)
        
        // Could also use `by atomic()` from `kotlinx.atomicfu`
        private var isClosed: Boolean by atomic(false)
    
        val current: RowType?
            get() = _current
    
        override fun close() {
            isClosed = true
        }
    
        override fun getBytes(index: Int) = throw IllegalStateException()
        override fun getDouble(index: Int) = throw IllegalStateException()
        override fun getLong(index: Int) = throw IllegalStateException()
        override fun getString(index: Int) = throw IllegalStateException()
    
        override fun next(): Boolean {
            if (isClosed) {
                throw IllegalStateException("The cursor is closed")
            }
            
            if (results.hasNext()) {
                _current = results.next()
                return true
            }
    
            return false
        }
    
    }
    
    class IterableQuery<RowType : Any>(private val results: Iterable<RowType>) : Query<RowType>(
        queries = mutableListOf(),
        mapper = { cursor -> @Suppress("UNCHECKED_CAST") (cursor as IteratorCursor<RowType>).current!! }
    ) {
        override fun execute() = IteratorCursor(results.iterator())
    }
    

    Having these pieces you could write test stub code like the following:

    given(queries).invocation { getOfflineRatesByBase(currencyResponse.base) }
      .thenReturn(IterableQuery(listOf(offlineRates)))
    
    opened by Nillerr 1
  • [Proposal] Mock Everything

    [Proposal] Mock Everything

    Description

    It is common in the Java world to not want to introduce an interface only for the sake of testing, due to Java classes and members being non-final by default. Mockative can enable mocking of open and abstract classes and members by generating mocks for these the same as they're currently generated for interface types. The catch is we'll need to recursively generate mocks for the dependencies of these classes as well, in order to construct instances of the mocks.

    Notes

    Generating mocks for open classes and members can also enable implicitly stubbing members like in Mockito, as long as the return types themselves are also open and can have mocks generated for them. While this may be more feasible with class mocks, it is not a goal of this proposal.

    enhancement 
    opened by Nillerr 0
  • [Feature] Spies

    [Feature] Spies

    Spies is a stable feature of popular mocking frameworks, and as such, support for spies in Mockative is of interest. We should be able to facilitate the implementation of spies by generating code that delegates to a constructor-provided delegate, with an accompanying <T> spy(KClass<T>, T) function.

    abstract class Spyable : Mockable() {
        fun <R> spy(name: String, arguments: List<Any?>, callThrough: () -> R): R {
            return stub(name, arguments)?.let { it.invoke() as R } ?: callThrough()
        }
    }
    
    class GitHubAPISpy(private val subject: GitHubAPI) : Spyable(), GitHubAPI {
        fun repository(name: String): Repository = 
            spy("repository", listOf<Any?>(name)) { subject.repository(name) }
    }
    
    fun spy(type: KClass<GitHubAPI>, subject: GitHubAPI): GitHubAPI = GitHubAPISpy(subject)
    
    class GitHubAPITests {
        private val realApi = GitHubAPIImpl()
    
        @Spy
        private val api = spy(classOf<GitHubAPI>(), realApi)
    }
    
    enhancement 
    opened by Nillerr 1
Releases(v1.3.0)
  • v1.3.0(Dec 14, 2022)

    What's Changed

    • Update Kotlin to 1.7.20 and Android plugin https://github.com/mockative/mockative/pull/52/commits/97741815900d8de982d32a2bef25d35318e230a3
    • Add support for the Kotlin/JS IR compiler.

    Full Changelog: https://github.com/mockative/mockative/compare/v1.2.6...v1.3.0

    Source code(tar.gz)
    Source code(zip)
  • v1.2.6(Jun 28, 2022)

    What's Changed

    • Add default/fallback implementations of functions from Any by @Nillerr in https://github.com/mockative/mockative/pull/43

    Full Changelog: https://github.com/mockative/mockative/compare/v1.2.5...v1.2.6

    Source code(tar.gz)
    Source code(zip)
  • v1.2.5(Jun 8, 2022)

    What's Changed

    • Adds builders for stubbing and verification with less type info by @Nillerr in https://github.com/mockative/mockative/pull/40

    Full Changelog: https://github.com/mockative/mockative/compare/v1.2.4...v1.2.5

    Source code(tar.gz)
    Source code(zip)
  • v1.2.4(Jun 7, 2022)

    What's Changed

    • Generate mocks for nested interfaces correctly, fixing #38 by @Nillerr in https://github.com/mockative/mockative/pull/39

    Full Changelog: https://github.com/mockative/mockative/compare/v1.2.3...v1.2.4

    Source code(tar.gz)
    Source code(zip)
  • v1.2.3(Jun 2, 2022)

    What's Changed

    • Fix lack of support for partial generic typealias as reported in #33 by @Nillerr in https://github.com/mockative/mockative/pull/35

    Full Changelog: https://github.com/mockative/mockative/compare/v1.2.2...v1.2.3

    Source code(tar.gz)
    Source code(zip)
  • v1.2.2(Jun 2, 2022)

    What's Changed

    • Support typealiases, fixing #33 by @Nillerr in https://github.com/mockative/mockative/pull/34

    Full Changelog: https://github.com/mockative/mockative/compare/v1.2.1...v1.2.2

    Source code(tar.gz)
    Source code(zip)
  • v1.2.1(May 14, 2022)

    What's Changed

    • Remove this argument from generated properties, fixing a bug causing generated code to be incompatible.

    Full Changelog: https://github.com/mockative/mockative/compare/v1.2.0...v1.2.1

    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(May 14, 2022)

    What's Changed

    • Completely rewritten code generation to use KotlinPoet
    • Update Kotlin and KSP versions to 1.6.20
    • Support incremental processing by splitting generated code into separate files and reducing file dependencies
    • Add function to test wildcard generics to address #29
    • Add support for extension receivers, fixing #30
    • Add an expect/actual interface to address #31
    Source code(tar.gz)
    Source code(zip)
  • v1.1.4(Jan 6, 2022)

    What's Changed

    • Support overriding stubs by @Nillerr in https://github.com/mockative/mockative/pull/24

    Full Changelog: https://github.com/mockative/mockative/compare/v1.1.3...v1.1.4

    Source code(tar.gz)
    Source code(zip)
  • v1.1.3(Dec 22, 2021)

    What's Changed

    • Fixed mock members with generic type parmeters as return type by @Nillerr in https://github.com/mockative/mockative/pull/21

    Full Changelog: https://github.com/mockative/mockative/compare/v1.1.2...v1.1.3

    Source code(tar.gz)
    Source code(zip)
  • v1.1.2(Dec 17, 2021)

    What's Changed

    • Fixed a bug where invocations of throwing stubs were not recorded by @Nillerr in https://github.com/mockative/mockative/pull/18

    Full Changelog: https://github.com/mockative/mockative/compare/v1.1.1...v1.1.2

    Source code(tar.gz)
    Source code(zip)
  • v1.1.1(Dec 15, 2021)

    What's Changed

    • Fixes incorrect range verification when only using atLeast by @Nillerr in https://github.com/mockative/mockative/pull/17

    Full Changelog: https://github.com/mockative/mockative/compare/v1.1.0...v1.1.1

    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Dec 13, 2021)

    What's Changed

    • Upgrade to Kotlin 1.6.0 by @Nillerr in https://github.com/mockative/mockative/pull/16
    • Support more Kotlin/Native targets by @Nillerr in https://github.com/mockative/mockative/pull/16

    The full list of supported targets now includes:

    • Windows
      • mingwX32
      • mingwX64
    • Linux
      • linuxX64
      • linuxArm32Hfp
      • linuxArm64
    • JVM (& Android)
    • JavaScript
      • browser
      • nodejs
    • wasm
      • wasm32
    • Darwin
      • iOS
        • iosX64
        • iosArm64
        • iosSimulatorArm64
      • watchOS
        • watchosArm32
        • watchosArm64
        • watchosX86
        • watchosX64
        • watchosSimulatorArm64
      • tvOS
        • tvosArm64
        • tvosX64
        • tvosSimulatorArm64
      • macOS
        • macosX64
        • macosArm64

    Full Changelog: https://github.com/mockative/mockative/compare/v1.0.7...v1.1.0

    Source code(tar.gz)
    Source code(zip)
  • v1.0.7(Dec 7, 2021)

    What's Changed

    • Fixes an incremental android compilation issue

    Full Changelog: https://github.com/mockative/mockative/compare/v1.0.6...v1.0.7

    Source code(tar.gz)
    Source code(zip)
  • v1.0.6(Nov 25, 2021)

    What's Changed

    • Implicit stubbing of members returning Unit by @Nillerr in https://github.com/mockative/mockative/pull/8
    • Updates error messages to include classOf<T> syntax by @Nillerr

    Full Changelog: https://github.com/mockative/mockative/compare/v1.0.4...v1.0.6

    Source code(tar.gz)
    Source code(zip)
  • v1.0.4(Nov 24, 2021)

    What's Changed

    • Add support for iOS simulators on ARM64 by @Nillerr in https://github.com/mockative/mockative/pull/2
    • Add support for mocks with generic type parameters by @Nillerr in https://github.com/mockative/mockative/pull/1

    Full Changelog: https://github.com/mockative/mockative/compare/v1.0.3...v1.0.4

    Source code(tar.gz)
    Source code(zip)
  • v1.0.3(Nov 17, 2021)

  • v1.0.2(Nov 17, 2021)

  • v1.0.1(Nov 17, 2021)

Owner
Mockative
Kotlin/Native and Kotlin Multiplatform mocking framework
Mockative
Exploring Kotlin Symbol Processing - KSP. This is just an experiment.

KSP example Exploring Kotlin Symbol Processing - KSP. This is just an experiment. Project contains 2 modules Processing Example Processing module is t

Merab Tato Kutalia 12 Aug 23, 2022
Kotlin Symbol Processing (KSP) sample project

Kotlin Symbol Processing (KSP) Sample Project Sample annotation processor created with Kotlin Symbol Processing (KSP) API. The repository supplements

Pavlo Stavytskyi 33 Dec 23, 2022
glide's ksp compiler ,use kotlin symbol processor

glide-ksp glide's ksp compiler ,use kotlin symbol processor requirements library version kotlin >= 1.6.10 ksp 1.6.10-1.0.2 usage add jitpack repositor

Mistletoe 24 Oct 17, 2022
🎲 Kotlin Symbol Processor to auto-generate extensive sealed classes and interfaces for Android and Kotlin.

SealedX ?? Kotlin Symbol Processor to auto-generate extensive sealed classes and interfaces for Android and Kotlin. Why SealedX? SealedX generates ext

Jaewoong Eum 236 Nov 30, 2022
Kotlin Symbol Processor library to create Mutable and Immutable variants of objects.

implier Kotlin Symbol Processor plugin to create Mutable and Immutable variants of objects. Examples @ImmutableImpl @MutableImpl public interface Samp

Vadim Yaroschuk 14 Nov 8, 2022
A Kotlin Symbol Processor to list sealed object instances.

Sealed Object Instances A Kotlin Symbol Processor to list sealed object instances. Usage Let's say you have a similar structure of sealed classes (or

Simon Marquis 17 Nov 17, 2022
android webview loader using ksp

KSPWebViewLoader ?? @WebViewBuilder Annotation can be automating your webview settings. (WIP) How to use @WebViewBuilder( url = "https://www.googl

sehee Jeong 8 Apr 8, 2022
Image Processing Engine with GUI

Image Processing Engine with GUI Imperial College London Department of Computing Third Year Software Engineer Group Project Supervisor: Dr. Pancham Sh

null 1 Jan 14, 2022
Simplify the processing of sealed class/interface

shiirudo Generates DSL to simplify processing branching by when expressions in sealed class/interface. Setup Refer to the KSP quickstart guide to make

KeitaTakahashi 2 Nov 1, 2022
KSP extension for the kotlin-maven-plugin

kotlin-maven-symbol-processing Extension for the kotlin-maven-plugin to support Kotlin Symbol Processing (KSP). Usage To use this extension, add the d

Dyescape 19 Dec 18, 2022
KSP annotation processor for Toothpick

toothpick-ksp KSP annotation processor for Toothpick. All credits go to olivierperez/ksp for the initial work on a KSP processor. Bear in mind this is

null 0 Oct 19, 2021
A collection of code generators powered by ksp.

AutoKsp A collection of code generators powered by ksp. status: working in progress Projects AutoGradlePlugin - Generate gradle plugin properties file

shenghaiyang 0 Nov 8, 2021
Ksp-di-library - Small library for DI in KMM apps

DI-KSP Small library for DI in KMM apps. Uses KSP for processing DI annotations:

Anna Zharkova 3 Feb 6, 2022
Ktorm KSP extension to help generate boilerplate code.

Ktorm KSP extension to help generate boilerplate code. It can automatically generate Table objects through entity classes, while making entities defined by data classes easier to use, and supports custom extension code generation logic.

KTORM.ORG 24 Dec 30, 2022
KSP-based library that generates lists from your annotation usages

ListGen, Generate Lists From Functions That Have @Listed Annotations! Welcome to ListGen! ListGen is a KSP-based library that can generate lists (and

Adib Faramarzi 24 Dec 6, 2022
A ksp library to automatically generate navigation functions for jetpack compose.

Compose/Navigation/Generator ⚠️ This library is still under development and not considered stable! Content Introduction Usage Example: Single destinat

Steffen Eckardt 4 Sep 13, 2022
This Kotlin Multiplatform library is for accessing the TMDB API to get movie and TV show content. Using for Android, iOS, and JS projects.

Website | Forum | Documentation | TMDb 3 API Get movie and TV show content from TMDb in a fast and simple way. TMDb API This library gives access to T

Moviebase 37 Dec 29, 2022
MMKV for Kotlin Multiplatform is a wrapper for MMKV using Kotlin API

MMKV for Kotlin Multiplatform is a wrapper for MMKV using Kotlin API

Ctrip, Inc. 65 Dec 29, 2022