Quarkusのテストでio.mockk.MockKExceptionがでてInjectMockができない

# はじめに

Quarkusを仕事で利用しており、APIを作成していたので自分でも実装しようと思いやってみたのですが、どうしても単体テストが通らない問題が起きてかなり時間を使っったので回避策をまとめてみます

# 問題

以下のコードでUsecaseの単体テストを行いました

```kotlin:GetDiaryUsecase.kt
package com.sample.usecase

import com.sample.domain.Diary
import com.sample.domain.DiaryId
import com.sample.usecase.port.DiaryPort
import io.mockk.every
import io.mockk.mockk
import io.quarkus.test.junit.QuarkusTest
import io.quarkus.test.junit.mockito.InjectMock
import jakarta.inject.Inject
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test

@QuarkusTest
class GetDiaryUsecaseTest {

    @Inject
    private lateinit var target: GetDiaryUsecase

    @InjectMock
    private lateinit var diaryPort: DiaryPort

    @Test
    fun DiaryIdをもとにDiaryを取得できること() {
        val diaryId = mockk<DiaryId>()
        val diary = mockk<Diary>()

        every { diaryPort.find(diaryId) } returns diary
        Assertions.assertEquals(diary, target.execute(diaryId))
    }

}
```

```kotlin:usecase/GetDiaryUsecase.kt
package com.sample.usecase

import com.sample.domain.Diary
import com.sample.domain.DiaryId
import com.sample.usecase.port.DiaryPort
import jakarta.enterprise.context.ApplicationScoped

@ApplicationScoped
class GetDiaryUsecase(private val diaryPort: DiaryPort) {
    fun execute(diaryId: DiaryId): Diary {
        return diaryPort.find(diaryId)
    }
}
```

```kotlin:usecase/port/DiaryPort.kt
package com.sample.usecase.port

import com.sample.domain.Diary
import com.sample.domain.DiaryId

interface DiaryPort {
    fun find(diaryId: DiaryId): Diary
}
```

```donmain/Diary.kt
package com.sample.domain

import java.time.LocalDateTime

data class Diary(val title: DiaryTitle, val body: DiaryBody, val author: DiaryAuthor, val releaseDate: DiaryReleaseDate)

data class DiaryId(val value: String)
data class DiaryTitle(val value: String)
data class DiaryBody(val value: String)
data class DiaryAuthor(val value: String)
data class DiaryReleaseDate(val value: LocalDateTime)
```

しかし以下のエラーが発生しました

```
2023-05-25 08:02:20,079 ERROR [io.qua.test] (Test runner thread) Test GetDiaryUsecaseTest#DiaryIdをもとにDiaryを取得できること() failed 
 [Error Occurred After Shutdown]: io.mockk.MockKException: Missing mocked calls inside every { ... } block: make sure the object inside the block is a mock
        at io.mockk.impl.recording.states.StubbingState.checkMissingCalls(StubbingState.kt:14)
        at io.mockk.impl.recording.states.StubbingState.recordingDone(StubbingState.kt:8)
        at io.mockk.impl.recording.CommonCallRecorder.done(CommonCallRecorder.kt:47)
```

DiaryPortがモックオブジェクトじゃないと言われてしまいました、、

# 原因1

まずは`Gateway`が存在しないことがありました
usecaseをTDDに書いているのになぜGatewayが必要なんだとは思いますが、Gatewayを削除するとエラーになるため作成しまいた

```kotlin:gateway/GetDiaryGateway.kt
package com.sample.gateway

import com.sample.domain.Diary
import com.sample.domain.DiaryId
import com.sample.driver.DiaryDriver
import com.sample.usecase.port.DiaryPort
import jakarta.enterprise.context.ApplicationScoped

@ApplicationScoped
class GetDiaryGateway(private val diaryDriver: DiaryDriver) : DiaryPort {
    override fun find(diaryId: DiaryId): Diary {
        TODO()
    }
}
```

しかしまだエラーは同じものがでています

これは実際に動いているテストから判明したことになります
まだ修正は必要そうです

# 原因2

いろいろ試行錯誤したところ`jakarta`からインポートしているのがテストの`Inject`とうまく噛み合っていないことがわかりました

そこで`pom.xml`を修正しました

```xml:pom.xml
    <quarkus.platform.version>3.0.2.Final</quarkus.platform.version>
　　　　　　　↓
    <quarkus.platform.version>2.16.5.Final</quarkus.platform.version>
```

このように変更することで`jakarta`から`javax`からライブラリを読み込むようになりテストが動きました

# おわりに

ではプラットフォーム3系でjakartaを使って動かすにはどうすればよいかという疑問は残るので引き続き調査していきます

動いているレポジトリが存在することはデバックができるのでとても助かるなという気持ちになります