2014-03-27 98 views
2

我想测试,当一个协作者接收到方法调用Mockito将接受验证,如果只有某个属性被正确设置。因此,逻辑是这样的:使用Hamcrest hasProperty与Specs2/Mockito

  • 下测试类调用一个合作者的说法
  • 下测试类构造一个新的对象传递给合作者
  • 的Mockito验证进行呼叫,如果传递的对象具有特定的属性设置

代码明智的什么我到目前为止是:

class ExampleSpec extends Specification with Mockito with Hamcrest { 
    val collaborator = mock[TargetObject] 

    "verifying a mock was called" should { 
     "match if a field on the called parameter was the same" in { 
     val cut = new ClassUnderTest(collaborator) 
     cut.execute(); 
     there was one(collaborator).call(anArgThat(hasProperty("first", CoreMatchers.equalTo("first")))) 
     } 
    } 
} 

w ^这里定义的类是:

class ClassUnderTest(collaborator: TargetObject) { 
    def execute() = 
     collaborator.call(new FirstParameter("first", "second")) 
} 

class FirstParameter(val first: String, val second: String) { 

} 

trait TargetObject { 
    def call(parameters: FirstParameter) 
} 

在香草Java的我会做到这一点无论是与Hamcrest hasProperty匹配(如上试过)或通过实现我自己的FeatureMatcher提取我想要的领域。以上错误代码如下:

java.lang.Exception: The mock was not called as expected: 
Argument(s) are different! Wanted: 
targetObject.call(
    hasProperty("first", "first") 
); 
-> at example.ExampleSpec$$anonfun$1$$anonfun$apply$2$$anonfun$apply$1.apply$mcV$sp(ExampleSpec.scala:18) 
Actual invocation has different arguments: 
targetObject.call(
    FirstParameter(first,second) 
); 

诊断并没有真正地告诉我很多。有没有办法做到这一点,我想如何用Hamcrest匹配器,或理想情况下更符合Specs2做到这一点?

回答

1

的惯用方法是使用MatcherMacros性状(在specs2-matcher-extra 2.3.10

import org.specs2.mock.Mockito 
import org.specs2.matcher._ 

class TestSpec extends org.specs2.mutable.Specification with Mockito with MatcherMacros { 
    val collaborator = mock[TargetObject] 

    "verifying a mock was called" should { 
    "match if a field on the called parameter was the same" in { 
     val cut = new ClassUnderTest(collaborator) 
     cut.execute 
     there was one(collaborator).call(matchA[FirstParameter].first("first")) 
    } 
    } 
} 

class ClassUnderTest(collaborator: TargetObject) { 
    def execute = collaborator.call(FirstParameter("first", "second")) 
} 

case class FirstParameter(first: String, second: String) 

trait TargetObject { 
    def call(parameters: FirstParameter) 
} 

在上述matchA代码被用于匹配FirstParametermatchAfirst方法对应于FirstParameterfirst值类。在这个例子中,我只是通过期望值,但你也可以通过另一个specs2匹配器,例如startWith("f"),或者甚至是一个函数(s: String) => s must haveSize(5)

+0

多数民众赞成真棒谢谢;我的真实数据是使用一个选项而不是一个直接的值。你知道我该如何解决这个问题吗? – tddmonkey

+0

有像'beSome(value)'或'beSome(startWith(“s”))或'beSome((v:String)=> v必须有size(2))'或'beNone'这样的'Option'的匹配器。 – Eric