如何在Groovy中使用多个MockFor? [英] How do I get multiple MockFor working in Groovy?
问题描述
我正在尝试让多种模拟在Groovy中工作.我设法做到这一点的唯一方法是创建自己的模拟程序-添加元方法.
I am trying to get multiple mocks working in groovy. The only way I have managed to get this working is to create my own kind of mock - adding a meta method.
我尝试使用嵌套的use语句,还尝试了一种用法和一个带有verify的代理,但两者均无效.两者都返回失败-"junit.framework.AssertionFailedError:此时不再需要对'pop'的调用.需求结束."
I have tried using nested use statements and also tried one use and one proxy with verify, neither of which worked. Both of these returned a failure - "junit.framework.AssertionFailedError: No more calls to 'pop' expected at this point. End of demands."
import groovy.mock.interceptor.MockFor
import org.junit.Test
class MockTest {
// results in No more calls to 'pop' expected at this point. End of demands.
@Test
public void testMock() {
MockFor pupilMock = new MockFor(Pupil)
MockFor bubbleMock = new MockFor(SomeService)
GroovyObject bubbleProxy = bubbleMock.proxyInstance()
pupilMock.demand.blowBubble { String colour ->
return bubbleProxy
}
bubbleMock.demand.pop {}
pupilMock.use {
bubbleMock.use {
Teacher teacher = new Teacher()
teacher.lesson("red")
}
}
}
// results in No more calls to 'pop' expected at this point. End of demands.
@Test
public void testProxy() {
MockFor pupilMock = new MockFor(Pupil)
MockFor bubbleMock = new MockFor(SomeService)
GroovyObject bubbleProxy = bubbleMock.proxyInstance()
pupilMock.demand.blowBubble { String colour ->
return bubbleProxy
}
bubbleMock.demand.pop {}
pupilMock.use {
Teacher teacher = new Teacher()
teacher.lesson("red")
}
bubbleMock.verify(bubbleProxy)
}
// only using a single mock so works
@Test
public void testMetaclass() {
MockFor pupilMock = new MockFor(Pupil)
SomeService.metaClass.pop = { println "pop was called" }
SomeService metaBubble = new SomeService("red")
pupilMock.demand.blowBubble { String colour ->
return metaBubble
}
pupilMock.use {
Teacher teacher = new Teacher()
teacher.lesson("red")
}
}
}
class Teacher {
public void lesson(String colour) {
Pupil pupil = new Pupil()
SomeService bubble = pupil.blowBubble(colour)
bubble.pop()
}
}
class Pupil {
SomeService blowBubble(String colour) {
SomeService child = new SomeService(colour)
return child
}
}
class SomeService {
String colour
SomeService(String colour) {
this.colour = colour
}
void pop() {
println "popped ${colour}"
}
}
重新评论模拟从方法构造和返回的东西,这就是我的方法...
Re comment about mocking something constructed and returned from a method, this is how I do it...
@Test
public void testMockReturned() {
MockFor bubbleMock = new MockFor(SomeService)
bubbleMock.demand.pop {}
bubbleMock.use {
Pupil pupil = new Pupil()
SomeService service = pupil.blowBubble("red")
service.pop()
}
}
推荐答案
在这种情况下,Pupil
应该是一个存根,因为您仅使用它来注入bubbleProxy
以便可以对其进行验证.像这样
In this case, Pupil
should be a stub since you're only using it to inject bubbleProxy
to you can perform verification against it. Like this,
import groovy.mock.interceptor.*
import org.junit.Test
class MockTest {
@Test
public void testMock() {
StubFor pupilMock = new StubFor(Pupil)
MockFor bubbleMock = new MockFor(SomeService)
GroovyObject bubbleProxy = bubbleMock.proxyInstance()
pupilMock.demand.blowBubble { String colour ->
return bubbleProxy
}
bubbleMock.demand.pop {}
bubbleMock.use {
Teacher teacher = new Teacher()
teacher.lesson("red")
}
}
}
此外,我相信调用proxyInstance()
时,需求会复制到代理上,因此您需要在实例化代理之前对需求进行配置.
但是,我不认为多个模拟存在问题,我认为您不能将实例模拟和类模拟混合在一起(您正在使用SomeService
进行此操作).我能想到的最小的例子证明了这一点
Also, I believe the demands are copied onto the proxy when proxyInstance()
is called, so you need to have your demands configured before instantiating the proxy.
However, I don't think there's a problem with multiple mocks, I think you just can't mix instance and class mocks (which you are doing with SomeService
). The smallest example I could think of that demonstrates this was
import groovy.mock.interceptor.MockFor
// this works
missyMock = new MockFor(Missy)
missyMock.demand.saySomethingNice {}
missy = missyMock.proxyInstance()
missy.saySomethingNice()
missyMock.verify(missy)
// as does this
missyMock = new MockFor(Missy)
missyMock.demand.saySomethingNice {}
missyMock.use {
new Missy().saySomethingNice()
}
// this don't
missyMock = new MockFor(Missy)
missyMock.demand.saySomethingNice {}
missy = missyMock.proxyInstance()
missyMock.use { // fails here in use()'s built-in verify()
missy.saySomethingNice()
}
missyMock.verify(missy)
class Missy {
void saySomethingNice() {}
}
为演示带有嵌套use
闭包的多重模拟的工作原理,请查看此人为设计的示例
To demonstrate that the multiple mocks with nested use
closures works, look at this contrived example
import groovy.mock.interceptor.MockFor
import org.junit.Test
class MockTest {
@Test
public void testMock() {
MockFor lessonMock = new MockFor(Lesson)
MockFor pupilMock = new MockFor(Pupil)
lessonMock.demand.getLessonPlan {}
pupilMock.demand.getName {}
pupilMock.use {
lessonMock.use {
Teacher teacher = new Teacher()
Pupil pupil = new Pupil()
Lesson lesson = new Lesson()
teacher.teach(pupil, lesson)
}
}
}
}
class Teacher {
void teach(Pupil pupil, Lesson lesson) {
println "Taught ${pupil.getName()} $lesson by ${lesson.getLessonPlan()}"
}
}
class Pupil {
String name
}
class Lesson {
LessonPlan lessonPlan
static class LessonPlan {}
}
这篇关于如何在Groovy中使用多个MockFor?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!