How to port a python monkeypatch in kotlin

51 Views Asked by At

Let me start by giving you some background, LakeFS has:

  • two automatically generated clients, one for Python and one for Java
  • an high-level wrapper, unfortunately Python-only

I rewrote the latter for Kotlin here, now I'm writing/porting some tests, in particular this one

def test_branch_create(monkeypatch):
    branch = get_test_branch()
    source = "main"
    with monkeypatch.context():
        def monkey_create_branch(_self, repo_name, branch_creation, *_):
            assert repo_name == branch.repo_id
            assert branch_creation.name == branch.id
            assert branch_creation.source == source
            return lakefs_sdk.BranchCreation(name=branch.id, source=source)

        monkeypatch.setattr(lakefs_sdk.BranchesApi, "create_branch", monkey_create_branch)
        branch.create(source)

where they mock the original BranchesApi.create_branch here

On JVM, branch.create(source) calls this:

fun create(sourceReference: ReferenceType, existOk: Boolean = false): Branch {
    val referenceId = getId(sourceReference)
    val branchCreation = BranchCreation().name(id).source(referenceId)
    try {
        client.branchesApi.createBranch(repoId, branchCreation).execute()
    } catch (e: ApiException) {
        if (!existOk)
            throw e
    }
    return this
}

where client: ApiClient is a property of the (last) super class and branchesApi is nothing more than a simple getter

val ApiClient.branchesApi: BranchesApi
    get() = BranchesApi(this)

BranchesApi::createBranch comes from the generated Java client here:

public APIcreateBranchRequest createBranch(String repository, BranchCreation branchCreation) {
    return new APIcreateBranchRequest(repository, branchCreation);
}

and then APIcreateBranchRequest::execute here will execute the REST API request:

public String execute() throws ApiException {
    ApiResponse<String> localVarResp = createBranchWithHttpInfo(repository, branchCreation);
    return localVarResp.getData();
}

So the part to mock to disable the real REST Api call, in my case on the JVM, has to be this last APIcreateBranchRequest::execute and not BranchesApi::createBranch like on Python

So far, my test file looks like this:

    val testRepo = Repo("test_repo", testClient)
    val testBranch = testRepo branch "test_branch"

    @Test
    fun testBranchCreate() {

        val branch = testBranch
        val source = "main"
        mockkConstructor(APIcreateBranchRequest::class)
        every {
            anyConstructed<APIcreateBranchRequest>().execute()
        } answers { "" }

        branch.create(source)
    }

In order to call those asserts, I need to find a way to either capture:

  • the APIcreateBranchRequest class instance
  • the APIcreateBranchRequest (private) constructor arguments

But after many hours and attempts, I couldn't figure out a way

0

There are 0 best solutions below