2014-12-04 66 views
16

我用用的Mockito scalatest。使用具有值類的匹配器時,我遇到以下問題。匹配器的Mockito,斯卡拉值類和NullPointerException異常

import org.scalatest.FlatSpec 
import org.scalatest.mock.MockitoSugar 
import org.mockito.BDDMockito._ 
import org.mockito.Matchers.any 

case class FirstId(val value: String) extends AnyVal 
case class SecondId(val value: String) extends AnyVal 

trait MockedClass { 
    def someMethods(firstId: FirstId, secondId: SecondId): Int 
} 

class ValueClassSpec() extends FlatSpec with MockitoSugar { 

    val mockedClass = mock[MockedClass] 
    val secondId = SecondId("secondId") 

    "Matchers" should "work for value class" in { 
    // given 
    given(mockedClass.someMethods(any[FirstId], org.mockito.Matchers.eq(secondId))).willReturn(3) 
    // when 
    val result = mockedClass.someMethods(FirstId("firstId"), secondId) 
    // then 
    assert(result == 3) 
    } 

} 

,其結果是:

ValueClassSpec: 
Matchers 
- should work for value class *** FAILED *** 
    java.lang.NullPointerException: 
    at io.scalac.fow.party.ValueClassSpec$$anonfun$1.apply$mcV$sp(ValueClassSpec.scala:22) 
    at io.scalac.fow.party.ValueClassSpec$$anonfun$1.apply(ValueClassSpec.scala:20) 
    at io.scalac.fow.party.ValueClassSpec$$anonfun$1.apply(ValueClassSpec.scala:20) 
    at org.scalatest.Transformer$$anonfun$apply$1.apply(Transformer.scala:22) 
    at org.scalatest.Transformer$$anonfun$apply$1.apply(Transformer.scala:22) 
    at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85) 
    at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104) 
    at org.scalatest.Transformer.apply(Transformer.scala:22) 
    at org.scalatest.Transformer.apply(Transformer.scala:20) 
    at org.scalatest.FlatSpecLike$$anon$1.apply(FlatSpecLike.scala:1639) 
    ... 

我發現類似的問題(Scala Value classes and Mockito Matchers don't play together),但沒有任何意見。

是否有posibility使用匹配器的Mockito與斯卡拉值類?

庫版本:2.11.2階,1.10.8的Mockito,scalatest 2.1.6

+0

afaik'any'和'eq'不能一起使用。 – Ashalynd 2014-12-04 08:57:30

+0

@Ashalynd - 從[文件的Mockito(http://mockito.github.io/mockito/docs/current/org/mockito/Mockito.html):**警告在參數匹配器:** 如果您正在使用參數匹配者,所有的論據都必須由匹配者提供。 例如:(示例顯示驗證,但同樣適用於存根): 驗證(模擬).someMethod(anyInt(),anyString(),eq(「第三個參數」)); 上述//是正確的 - EQ()也是一個參數匹配 – 2014-12-04 09:07:15

回答

19

正確的解決方案是:

case class StringValue(val text: String) extends AnyVal 
case class LongValue(val value: Long) extends AnyVal 

val eqFirst: StringValue = StringValue(org.mockito.Matchers.eq("first")) 
val anySecond: StringValue = StringValue(org.mockito.Matchers.any[String]) 

val eqFirst: LongValue = LongValue(org.mockito.Matchers.eq(1L)) 
val anySecond: LongValue = LongValue(org.mockito.Matchers.any[Long]) 
+0

當我這樣做,我得到了一堆警告和錯誤的關於不使用磕碰之外的匹配: VAL anyProjectName = org.mockito.ArgumentMatchers.any [字符串] .asInstanceOf [項目] org.mockito.exceptions。濫用。InvalidUseOfMatchersException: 在此處檢測到錯位或誤用的參數匹配: – 2017-08-30 18:51:18

9

我找到了解決辦法:

val anyFirstId: FirstId = any[String].asInstanceOf[FirstId] 
val eqSecondId: SecondId = org.mockito.Matchers.eq[String](secondId.value).asInstanceOf[SecondId] 
given(mockedClass.someMethods(anyFirstId, eqSecondId)).willReturn(3) 
+0

如果實現自己的匹配爲AnyVals,並把它在GitHub上這將是冷靜。 – 2014-12-04 15:25:33

+0

爲AnyVal編寫通用eq匹配器並不容易。 – 2014-12-05 08:19:10

+0

這有效嗎?我得到一個ClassCastException。 – 2015-01-23 12:21:05

1

該作品各種extends AnyVal值類的,不需要特殊的匹配之一:

given(mockedClass.someMethods(FirstId(anyString), SecondId(org.mockito.Matchers.eq(secondId.value)))).willReturn(3)