kotlin
書いてて、mockito-inline
の mockStatic
を使おうとして
少し時間無駄にしたので、他の人が同じことで時間を無駄にしないように書いとく
tl;dr
@JvmStatic
のAnnotationをつける必要がある
普通に考えれば当たり前なんだけど、つけ忘れてた時にエラー出てなんでだっけ?ってなる
object ExampleObject { @JvmStatic //これ fun static(): String { return "static" } }
なぜか
じゃないとバイトコードになった時に static
にならないので結果としてmock出来ずに失敗する
// ================com/example/springkotlin/utils/ExampleObject.class ================= // class version 52.0 (52) // access flags 0x31 public final class com/example/springkotlin/utils/ExampleObject { // access flags 0x19 public final static static()Ljava/lang/String; @Lkotlin/jvm/JvmStatic;() @Lorg/jetbrains/annotations/NotNull;() // invisible L0 LINENUMBER 6 L0 LDC "static" ARETURN L1 MAXSTACK = 1 MAXLOCALS = 0 // access flags 0x11 public final notStatic()Ljava/lang/String; @Lorg/jetbrains/annotations/NotNull;() // invisible L0 LINENUMBER 10 L0 LDC "notStatic" ARETURN L1 LOCALVARIABLE this Lcom/example/springkotlin/utils/ExampleObject; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 // access flags 0x2 private <init>()V L0 LINENUMBER 3 L0 ALOAD 0 INVOKESPECIAL java/lang/Object.<init> ()V RETURN L1 LOCALVARIABLE this Lcom/example/springkotlin/utils/ExampleObject; L0 L1 0 MAXSTACK = 1 MAXLOCALS = 1 // access flags 0x19 public final static Lcom/example/springkotlin/utils/ExampleObject; INSTANCE @Lorg/jetbrains/annotations/NotNull;() // invisible // access flags 0x8 static <clinit>()V L0 LINENUMBER 3 L0 NEW com/example/springkotlin/utils/ExampleObject DUP INVOKESPECIAL com/example/springkotlin/utils/ExampleObject.<init> ()V ASTORE 0 ALOAD 0 PUTSTATIC com/example/springkotlin/utils/ExampleObject.INSTANCE : Lcom/example/springkotlin/utils/ExampleObject; RETURN MAXSTACK = 2 MAXLOCALS = 1 @Lkotlin/Metadata;(mv={1, 6, 0}, k=1, d1={"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\u0008\u0002\n\u0002\u0010\u000e\n\u0002\u0008\u0002\u0008\u00c6\u0002\u0018\u00002\u00020\u0001B\u0007\u0008\u0002\u00a2\u0006\u0002\u0010\u0002J\u0006\u0010\u0003\u001a\u00020\u0004J\u0008\u0010\u0005\u001a\u00020\u0004H\u0007\u00a8\u0006\u0006"}, d2={"Lcom/example/springkotlin/utils/ExampleObject;", "", "()V", "notStatic", "", "static", "spring-kotlin"}) // compiled from: ExampleObject.kt }
エラー
エラーとしてはこんなのが出るけどぱっと見ですぐに気がつきにくい
when() requires an argument which has to be 'a method call on a mock'. For example: when(mock.getArticles()).thenReturn(articles); Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. Those methods *cannot* be stubbed/verified. Mocking methods declared on non-public parent classes is not supported. 2. inside when() you don't call method on mock but on some other object. org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. For example: when(mock.getArticles()).thenReturn(articles); Also, this error might show up because: 1. you stub either of: final/private/equals()/hashCode() methods. Those methods *cannot* be stubbed/verified. Mocking methods declared on non-public parent classes is not supported. 2. inside when() you don't call method on mock but on some other object.
コード
package com.example.springkotlin.utils object ExampleObject { @JvmStatic fun static(): String { return "static" } fun notStatic(): String { return "notStatic" } }
テスト
package com.example.springkotlin.utils import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Test import org.mockito.Mockito.mockStatic class ExampleObjectTest { @Test fun test() { // 雑 val mocked = mockStatic(ExampleObject::class.java) mocked.`when`<String>(ExampleObject::static).thenReturn("mocked") assertEquals("mocked", ExampleObject.static()) mocked.close() } }