我有一个Java类
class MyClass {
void methodA() {
//something
}
void methodB() {
//something else
}
}
我想单元测试方法A但方法A依赖于methodB。我已经完成了spock文档,但我无法找到如何处理这种情况。我该怎么办?
注意 我无法找到答案,所以我在stackoverflow上自我回答这个问题,允许as per stackoverlfow's self-answering policy。添加此注释以避免混淆那些不了解自我回复政策的人,所以不要删除。
答案 0 :(得分:2)
这是一种无需模拟覆盖所需方法的方法:
def "your spock test"() {
MyClass myClass = new MyClass() {
@Override
void methodB() {
// do something related to this test
}
}
expect:
//whatever you want to do
myClass.methodA()
}
答案 1 :(得分:2)
实际上已在spock文档中记录,请参阅partial mocks部分。
// this is now the object under specification, not a collaborator
def persister = Spy(MessagePersister) {
// stub a call on the same object
isPersistable(_) >> true
}
when:
persister.receive("msg")
then:
// demand a call on the same object
1 * persister.persist("msg")
答案 2 :(得分:1)
这样做的一个解决方案是在测试中执行以下操作
def "your spock test"() {
MyClass myClass = Mock(MyClass)
myClass.methodA() >> {
callRealMethod()
}
myClass.methodB() >> {
//your mocking logic
}
expect:
//whatever you want to do
}
callRealMethod允许您在通过spock进行模拟时调用实际的实现。
答案 3 :(得分:1)
我会稍微重新考虑这个解决方案,因为你在这里做的是you are testing mock instead of a real object。我不会在这个类中嘲笑任何东西,我会把它当作一个简单的单元。如果methodB
代表不同的单位范围,那么methodA
那么这可能是重构这个类并将methodB
中封装的职责提取到一个单独的类中的一个很好的起点,该类注入到您正在尝试的那个测试。然后嘲笑这个注入的课程在我看来更有意义。但首先总是问自己为什么要嘲笑,如果有更好的选择(嘲笑应该是你最后的选择值得考虑)。