2012-03-07 81 views
3

我在使用Mockito和Specs2模擬具有參數類型視圖邊界的方法時遇到了一個問題。簡單地說,由於結合的視圖轉換爲一個額外的隱含參數的方法,的Mockito無法調和通過期望值來描述實際的參數的模擬臨危呼叫:是否有可能嘲笑與Mockito和Specs2視圖範圍的Scala方法?

例如:

//Receiver.scala 
class Receiver { 
    def methodWithViewBound[T <% WrappedString](w : T) : Unit = { 
    //noop! 
    } 
} 

//WrappedString.scala 
class WrappedString(val wrapped : String) { 

} 

//TestMockedMethodWithViewBound.scala 
import org.specs2.mutable._ 
import org.specs2.specification._ 
import org.specs2.mock._ 
import org.mockito.Matchers 

class TestMockedMethodWithViewBound extends Specification with Mockito { 

    implicit def wrapString(s : String) : WrappedString = new WrappedString(s); 
    implicit def unwrapString(w : WrappedString) : String = w.wrapped; 

    "Mockito" should { 
    "Allow mocking of methods whose argument types include a view bound, using a matcher" in { 
     val receiver = mock[Receiver] 
     receiver.methodWithViewBound("Testing") 
     there was one(receiver).methodWithViewBound(Matchers.eq("Testing")) 
    } 


    "Allow mocking of methods whose argument types include a view bound, using an argument literal" in { 
     val receiver = mock[Receiver] 
     receiver.methodWithViewBound("Testing") 
     there was one(receiver).methodWithViewBound("Testing") 
    } 
    } 
} 

輸出這給出了:

[15:18:46] [[email protected] ../tim/Projects/MockitoTest] $ sbt test 
[info] Set current project to Mockito View Bounds Test (in build file:/home/tim/Projects/MockitoTest/) 
[info] Compiling 1 Scala source to /home/tim/Projects/MockitoTest/target/scala-2.9.1/test-classes... 
[info] Mockito should 
[error] x Allow mocking of methods whose argument types include a view bound 
[error]  The mock was not called as expected: 
[error] Invalid use of argument matchers! 
[error] 2 matchers expected, 1 recorded. 
[error] This exception may occur if matchers are combined with raw values: 
[error]  //incorrect: 
[error]  someMethod(anyObject(), "raw String"); 
[error] When using matchers, all arguments have to be provided by matchers. 
[error] For example: 
[error]  //correct: 
[error]  someMethod(anyObject(), eq("String by matcher")); 
[error] 
[error] For more info see javadoc for Matchers class. (TestMockedMethodWithViewBound.scala:12) 
[info] 
[info] 
[info] Total for specification TestMockedMethodWithViewBound 
[info] Finished in 175 ms 
[info] 1 example, 1 failure, 0 error 
[error] Failed: : Total 1, Failed 1, Errors 0, Passed 0, Skipped 0 
[error] Failed tests: 
[error]  TestMockedMethodWithViewBound 
[error] {file:/home/tim/Projects/MockitoTest/}default-3adcf2/test:test: Tests unsuccessful 
[error] Total time: 7 s, completed 07-Mar-2012 15:19:47 
[15:19:47] [[email protected] ../tim/Projects/MockitoTest] $ sbt test 
[info] Set current project to Mockito View Bounds Test (in build file:/home/tim/Projects/MockitoTest/) 
[info] Compiling 1 Scala source to /home/tim/Projects/MockitoTest/target/scala-2.9.1/test-classes... 
[info] Mockito should 
[error] x Allow mocking of methods whose argument types include a view bound, using a matcher 
[error]  The mock was not called as expected: 
[error] Invalid use of argument matchers! 
[error] 2 matchers expected, 1 recorded. 
[error] This exception may occur if matchers are combined with raw values: 
[error]  //incorrect: 
[error]  someMethod(anyObject(), "raw String"); 
[error] When using matchers, all arguments have to be provided by matchers. 
[error] For example: 
[error]  //correct: 
[error]  someMethod(anyObject(), eq("String by matcher")); 
[error] 
[error] For more info see javadoc for Matchers class. (TestMockedMethodWithViewBound.scala:12) 
[error] x Allow mocking of methods whose argument types include a view bound, using an argument literal 
[error]  The mock was not called as expected: 
[error] Argument(s) are different! Wanted: 
[error] receiver.methodWithViewBound(
[error]  "Testing", 
[error]  ($anonfun$apply$mcV$sp$2) <function1> 
[error]); 
[error] -> at TestMockedMethodWithViewBound$$anonfun$1$$anonfun$apply$6$$anonfun$apply$2.apply$mcV$sp(TestMockedMethodWithViewBound.scala:22) 
[error] Actual invocation has different arguments: 
[error] receiver.methodWithViewBound(
[error]  "Testing", 
[error]  ($anonfun$apply$7) <function1> 
[error]); 
[error] -> at TestMockedMethodWithViewBound$$anonfun$1$$anonfun$apply$6.apply(TestMockedMethodWithViewBound.scala:21) 
[error] (TestMockedMethodWithViewBound.scala:19) 
[info] 
[info] 
[info] Total for specification TestMockedMethodWithViewBound 
[info] Finished in 325 ms 
[info] 2 examples (+1), 2 expectations (+1), 2 failures (+1), 0 error 
[error] Failed: : Total 2, Failed 2, Errors 0, Passed 0, Skipped 0 
[error] Failed tests: 
[error]  TestMockedMethodWithViewBound 
[error] {file:/home/tim/Projects/MockitoTest/}default-3adcf2/test:test: Tests unsuccessful 
[error] Total time: 7 s, completed 07-Mar-2012 15:23:05 

...有沒有人碰到這個問題之前來了,或者遇到嘲諷使用specs2視圖邊界或隱含參數的方法的方法嗎?

感謝,

回答

1

蒂姆,我已經添加了驗證轉換參數最新specs2 1.9快照的可能性。

這仍然是實驗性的,因爲我不會產生什麼樣的不良影響。

例如,有一件事是,默認情況下任何Function1參數都會被驗證爲OK,因爲Mockito無法知道哪些函數是隱式轉換,哪些是「常規」參數。

+0

埃裏克,非常感謝!完全理解它的實驗,實際上,考慮它,我可以考慮幾種不同的(並且相互排斥的)含有可能是有效的隱含參數的方法,因此它不是一個明確的問題。但是,對於我的特殊用例來說這絕對是非常棒的,再次感謝! – mistertim 2012-03-08 10:10:34