Closure Mocking

2 views
Skip to first unread message

Julien

unread,
May 8, 2009, 3:05:33 AM5/8/09
to gmock-dev
I've start looking at closure mocking and writing some test about it.
I think I understand why we didn't really agree on the
keyword to use when returning.

I fact I am still confuse about what should be the correct behavior. I
would sometimes like the returns to be a
the actual value returned by the closure if matched like in the
following example:


void testInvokeArguments(){
def mockArray = mock()
mockArray.collect(invoke { it.name.returns("a name") }.returns
("apple", "arts"))

play {
def result = mockArray.collect { it.name.startsWith("a") }
assertEquals(["apple", "arts"], result)
}
}

But in the following one I would like to expect what the return should
be, like in the following example:

void testServer(){

def server = mock()
server.remote(invoke {
it.run("ls /").returns(["etc", "var", "tmp"])
}.returns("few files"))

play {
server.remote {
def root = run("ls /")
if (root.size() > 10){
return "many files"
} else {
return "few files"
}
}
}
}


You can see that this is two differents usages of the closure mocking.
And I nearly about to suggest a different
keyword to express those differents behavior, like here.

void testArguments(){

def array = mock()
array.sort( invoke(10, 20).shouldReturns(true).returns(20, 15, 10,
5) )
play {
def result = array.sort{ a,b -> b > a}
assertEquals([20, 15, 10, 5], result)
}

}

But I don't really like this idea. What's your opinions on this.

Johnny

unread,
May 8, 2009, 3:37:14 AM5/8/09
to gmoc...@googlegroups.com
I think you seem to confuse the result of a closure and the result of a
method. In your first example,

mockArray.collect(invoke { it.name.returns("a name") }.returns("apple",
"arts"))

["apple", "arts"] should be the result of 'collect' instead of the
closure. So, it should be

mockArray.collect(invoke { it.name.returns("a name") }).returns("apple",
"arts")

The second example is correct. The last example should be

array.sort( invoke(10, 20).shouldReturns(true) ).returns(20, 15, 10, 5)

I still suggest to use an optional 'should' property like:

array.sort( invoke(10, 20).should.returns(true) ).returns(20, 15, 10, 5)


What's more, I think we should talk about the 'it' keyword. Because 'it'
is a parameter of the closure, actually users should use
'invoke(aMockObject) {}' to mock 'it', but it is inconvenient to do so.
So I suggest: If users haven't provide a parameter for 'invoke', then
pass the mock object to the closure as a parameter.

And, I still insist on allowing using the 'delegate' keyword for closure
mocking. In your second example, 'def root = run("ls /")' is actually
'def root = delegate.run("ls /")', so it will be more consistent to
write 'delegate.run("ls /").returns(["etc", "var", "tmp"])', or just
'run("ls /").returns(["etc", "var", "tmp"])'


在 2009-05-08五的 00:05 -0700,Julien写道:

Julien

unread,
May 18, 2009, 2:14:30 AM5/18/09
to gmock-dev
You are right I was confusing the return of a method call and the one
of the closure. Sound better now.

I am questionning the real value of closure mocking. I can see when it
would be useful when closure is used as part of a dsl but not too sure
when it's like the sort.

On the second example it's a mistake to use 'it' and we can introduce
the delegate optional keyword: def root = delegate.run("ls /"), as you
suggest.

I am not too sure about how 'returns' should look like. We'll see
after some basic implementation.
Reply all
Reply to author
Forward
0 new messages