Quantcast

How to return another mock from a parmeterized call on a mock

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

How to return another mock from a parmeterized call on a mock

karfau
I have written the following spec:
https://github.com/karfau/graxle-table/blob/0983d48f5edf2d159518ac894ed8aeed4de2c3b8/src/test/groovy/de/karfau/graxle/model/TestMatrixTableModel.groovy#L27
    (feature "getValueAt( #x , #y ) uses get( #x , #y ) and returns
the content")

for the following implementation:
https://github.com/karfau/graxle-table/blob/0983d48f5edf2d159518ac894ed8aeed4de2c3b8/src/main/groovy/de/karfau/graxle/model/MatrixTableModel.java#L45
    (method public Object getValueAt(int rowIndex, int columnIndex) )

but I have no idea why it fails with
>
> Too few invocations for:
>
> 1 * stubCell.getContent()   (0 invocations)
>
> at org.spockframework.mock.InteractionScope.verifyInteractions(InteractionScope.java:66)
> at org.spockframework.mock.MockController.leaveScope(MockController.java:35)
> at de.karfau.graxle.model.TestMatrixTableModel.getValueAt( #x , #y ) uses get( #x , #y ) and returns the content(TestMatrixTableModel.groovy:32)
>
because I would expect the matrix-mock to return the stubCell instance
which it doesn't (that is why stubCell.getContent() is never called).

Any ideas or Questions about it?

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to return another mock from a parmeterized call on a mock

Peter Niederwieser
Administrator
Stubbing and mocking of the same call has to happen together. This
question comes up frequently. Search the Google group for a longer
explanation.

Cheers,
Peter

On Apr 22, 1:30 am, karfau <[hidden email]> wrote:

> I have written the following spec:https://github.com/karfau/graxle-table/blob/0983d48f5edf2d159518ac894...
>     (feature "getValueAt( #x , #y ) uses get( #x , #y ) and returns
> the content")
>
> for the following implementation:https://github.com/karfau/graxle-table/blob/0983d48f5edf2d159518ac894...
>     (method public Object getValueAt(int rowIndex, int columnIndex) )
>
> but I have no idea why it fails with
>
> > Too few invocations for:
>
> > 1 * stubCell.getContent()   (0 invocations)
>
> >    at org.spockframework.mock.InteractionScope.verifyInteractions(InteractionScop e.java:66)
> >    at org.spockframework.mock.MockController.leaveScope(MockController.java:35)
> >    at de.karfau.graxle.model.TestMatrixTableModel.getValueAt( #x , #y ) uses get( #x , #y ) and returns the content(TestMatrixTableModel.groovy:32)
>
> because I would expect the matrix-mock to return the stubCell instance
> which it doesn't (that is why stubCell.getContent() is never called).
>
> Any ideas or Questions about it?

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to return another mock from a parmeterized call on a mock

karfau
In reply to this post by karfau
There are two more things to say, they both don't solve the problem:
I have found and fixed the "matrix.get(y,y)" typo.
I have tried to change the order inside the "given:"-block.

The latest version is in the master branch,
Here are the links that match those from yesterday but always display the latest
version (master branch):

The spec is at
https://github.com/karfau/graxle-table/blob/master/src/test/groovy/de/karfau/graxle/model/TestMatrixTableModel.groovy#L27
the line could change, here we are talking about the feature method
 >"getValueAt( #x , #y ) uses get( #x , #y ) and returns the content"

The implementation is at
https://github.com/karfau/graxle-table/blob/master/src/main/groovy/de/karfau/graxle/model/MatrixTableModel.java#L45
the line could change, here we are talking about the method
 >public Object getValueAt(int rowIndex, int columnIndex)


karfau


Am 22.04.2012 01:30, schrieb karfau:

> I have written the following spec:
> https://github.com/karfau/graxle-table/blob/0983d48f5edf2d159518ac894ed8aeed4de2c3b8/src/test/groovy/de/karfau/graxle/model/TestMatrixTableModel.groovy#L27
>      (feature "getValueAt( #x , #y ) uses get( #x , #y ) and returns
> the content")
>
> for the following implementation:
> https://github.com/karfau/graxle-table/blob/0983d48f5edf2d159518ac894ed8aeed4de2c3b8/src/main/groovy/de/karfau/graxle/model/MatrixTableModel.java#L45
>      (method public Object getValueAt(int rowIndex, int columnIndex) )
>
> but I have no idea why it fails with
>>
>> Too few invocations for:
>>
>> 1 * stubCell.getContent()   (0 invocations)
>>
>> at org.spockframework.mock.InteractionScope.verifyInteractions(InteractionScope.java:66)
>> at org.spockframework.mock.MockController.leaveScope(MockController.java:35)
>> at de.karfau.graxle.model.TestMatrixTableModel.getValueAt( #x , #y ) uses get( #x , #y ) and returns the content(TestMatrixTableModel.groovy:32)
>>
> because I would expect the matrix-mock to return the stubCell instance
> which it doesn't (that is why stubCell.getContent() is never called).
>
> Any ideas or Questions about it?
>

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to return another mock from a parmeterized call on a mock

karfau
In reply to this post by Peter Niederwieser
Oh, this is great.
I found an explanation that I did understand even better then the docs
regarding this topic:
http://groups.google.com/group/spockframework/browse_frm/thread/8c364dd63b2e359b

And the resulting code is a version that I also tried yesterday after
my first mail:

>
> def "getValueAt( #x , #y ) uses get( #x , #y ) and returns the content"() {
>  def actual = false
>  given:
> 1 * matrix.get(x, y) >> stubCell
> 1 * stubCell.getContent() >> true
>  when:
> actual = model.getValueAt(x, y)
>  then:
> assert actual
>  where:
> x << [0, 0]
> y << [0, 1]
> }
>

but it throws another Error, that is why I thought it was the wrong
way to go:

>
> java.lang.IllegalAccessError: tried to access class de.karfau.graxle.model.Cell from class $Proxy12
> at de.karfau.graxle.model.MatrixTableModel.getValueAt(MatrixTableModel.java:52)
> at de.karfau.graxle.model.TestMatrixTableModel.getValueAt( #x , #y ) uses get( #x , #y ) and returns the content(TestMatrixTableModel.groovy:36)
>

Is there a way to tell the mock wich classes (Cell is an interface) it
needs to know?
I thought creating the stubCell like this
>
> Cell stubCell = Mock(Cell)
>
would make it an instance of Cell.

Until now this was already a lesson in being more aware of the type of
Error/Exception that is thrown :)

karfau

On 22 Apr., 02:46, Peter Niederwieser <[hidden email]> wrote:

> Stubbing and mocking of the same call has to happen together. This
> question comes up frequently. Search the Google group for a longer
> explanation.
>
> Cheers,
> Peter
>
> On Apr 22, 1:30 am, karfau <[hidden email]> wrote:
>
>
>
>
>
>
>
> > I have written the following spec:https://github.com/karfau/graxle-table/blob/0983d48f5edf2d159518ac894...
> >     (feature "getValueAt( #x , #y ) uses get( #x , #y ) and returns
> > the content")
>
> > for the following implementation:https://github.com/karfau/graxle-table/blob/0983d48f5edf2d159518ac894...
> >     (method public Object getValueAt(int rowIndex, int columnIndex) )
>
> > but I have no idea why it fails with
>
> > > Too few invocations for:
>
> > > 1 * stubCell.getContent()   (0 invocations)
>
> > >    at org.spockframework.mock.InteractionScope.verifyInteractions(InteractionScop e.java:66)
> > >    at org.spockframework.mock.MockController.leaveScope(MockController.java:35)
> > >    at de.karfau.graxle.model.TestMatrixTableModel.getValueAt( #x , #y ) uses get( #x , #y ) and returns the content(TestMatrixTableModel.groovy:32)
>
> > because I would expect the matrix-mock to return the stubCell instance
> > which it doesn't (that is why stubCell.getContent() is never called).
>
> > Any ideas or Questions about it?

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to return another mock from a parmeterized call on a mock

Peter Niederwieser
Administrator
On Apr 22, 2012, at 2:20 PM, Karfau wrote:

>> given:
>> 1 * matrix.get(x, y) >> stubCell
>> 1 * stubCell.getContent() >> true

Typically you would only stub in such a case but not mock (i.e. no '1 *').

> but it throws another Error, that is why I thought it was the wrong
> way to go:
>
>>
>> java.lang.IllegalAccessError: tried to access class de.karfau.graxle.model.Cell from class $Proxy12
>> at de.karfau.graxle.model.MatrixTableModel.getValueAt(MatrixTableModel.java:52)
>> at de.karfau.graxle.model.TestMatrixTableModel.getValueAt( #x , #y ) uses get( #x , #y ) and returns the content(TestMatrixTableModel.groovy:36)
>>
>
> Is there a way to tell the mock wich classes (Cell is an interface) it
> needs to know?

I don't understand the question.

> I thought creating the stubCell like this
>>
>> Cell stubCell = Mock(Cell)
>>
> would make it an instance of Cell.

It does. ('Cell stubCell = Mock()' or 'def stubCell = Mock(Cell)' will do.) Is Cell a plain, top-level interface?

Cheers,
Peter

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to return another mock from a parmeterized call on a mock

karfau


> >> given:
> >>        1 * matrix.get(x, y) >> stubCell
> >>        1 * stubCell.getContent() >> true
>
> Typically you would only stub in such a case but not mock (i.e. no '1 *').
>
I thought I did understand something, that is why i commented here:
http://code.google.com/p/spock/wiki/Interactions
Is the comment wrong? I did this so that I can have an expectation and
a return value at the same time.


> > but it throws another Error, that is why I thought it was the wrong
> > way to go:
>
> >> java.lang.IllegalAccessError: tried to access class de.karfau.graxle.model.Cell from class $Proxy12
> >>        at de.karfau.graxle.model.MatrixTableModel.getValueAt(MatrixTableModel.java:52 )
> >>        at de.karfau.graxle.model.TestMatrixTableModel.getValueAt( #x , #y ) uses get( #x , #y ) and returns the content(TestMatrixTableModel.groovy:36)
>
> It does. ('Cell stubCell = Mock()' or 'def stubCell = Mock(Cell)' will do.)
When writing one of those, my IDE (IntelliJ IDEA) gives me a warning
about an incompatible type assignment. writing it like I did doesn't.

>Is Cell a plain, top-level interface?
Yes, it is :
https://github.com/karfau/graxle-table/blob/master/src/main/groovy/de/karfau/graxle/model/Cell.java
and so is Matrix:
https://github.com/karfau/graxle-table/blob/master/src/main/groovy/de/karfau/graxle/model/Matrix.java

And the MatrixTableModel is also a java class:
https://github.com/karfau/graxle-table/blob/master/src/main/groovy/de/karfau/graxle/model/MatrixTableModel.java

The only thing that is groovy is the spec.

I think I will do another try in describing my use case:
The MatrixTableModel is set up with the matrix-mock.
when calling for a value it should ask the marix(-mock) for a cell
(the goal of the feature method is to set the returned cell to
stubCell)
if a cell was returned, its content is returned.
(the other goal of this feature method is to set the return value of
stubCell to true)

I really have no idea why it says what sounds to me like inside
MatrixTableModel it doesn't know about the "class" Cell. Which is
strange, because it has it all over.
But the message says something about "class $Prox12" which sounds like
something spock could be responsible for.
When debugging to the point where it throws it says
"$Proxy12" is "Mock for type 'Matrix' named 'matrix'"
And I digged even deeper: the stubCell instance is returned all the
way to the matrix instance
(via DefaultMockFactory line 70 "return
dispatcher.dispatch(invocation);") and then the next "step into" in
the debugger ends up in
"sun.instrument.InstrumentationImpl.transform():359" (inside the JRE
rt.jar the source doesn't seem to be available) where the second
argument is "java/lang/IllegalAccessError".
I commited a thread-dump:


If this helps: the whole project is at github and can be build with
gradle.
I commited the latest version I used for this result.

I hope this makes things more clear :)

karfau

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to return another mock from a parmeterized call on a mock

Peter Niederwieser
Administrator
On Apr 22, 2012, at 9:46 PM, karfau wrote:

>
>
>>>> given:
>>>>        1 * matrix.get(x, y) >> stubCell
>>>>        1 * stubCell.getContent() >> true
>>
>> Typically you would only stub in such a case but not mock (i.e. no '1 *').
>>
> I thought I did understand something, that is why i commented here:
> http://code.google.com/p/spock/wiki/Interactions
> Is the comment wrong? I did this so that I can have an expectation and
> a return value at the same time.

My suggestion was to leave off the '1 *' because you typically don't care if and how often getters are called. You just care about the return value.

>
>>> but it throws another Error, that is why I thought it was the wrong
>>> way to go:
>>
>>>> java.lang.IllegalAccessError: tried to access class de.karfau.graxle.model.Cell from class $Proxy12
>>>>        at de.karfau.graxle.model.MatrixTableModel.getValueAt(MatrixTableModel.java:52 )
>>>>        at de.karfau.graxle.model.TestMatrixTableModel.getValueAt( #x , #y ) uses get( #x , #y ) and returns the content(TestMatrixTableModel.groovy:36)
>>
>> It does. ('Cell stubCell = Mock()' or 'def stubCell = Mock(Cell)' will do.)
> When writing one of those, my IDE (IntelliJ IDEA) gives me a warning
> about an incompatible type assignment. writing it like I did doesn't.

IDEA will give a warning for the former but not the latter (and it can infer the type).

>> Is Cell a plain, top-level interface?
> Yes, it is :
> https://github.com/karfau/graxle-table/blob/master/src/main/groovy/de/karfau/graxle/model/Cell.java
> and so is Matrix:
> https://github.com/karfau/graxle-table/blob/master/src/main/groovy/de/karfau/graxle/model/Matrix.java

You have to make Cell public. The error message isn't very clear on this, but it's nothing that we can easily improve.

Cheers,
Peter

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: How to return another mock from a parmeterized call on a mock

karfau


On 22 Apr., 22:16, Peter Niederwieser <[hidden email]> wrote:

> >> It does. ('Cell stubCell = Mock()' or 'def stubCell = Mock(Cell)' will do.)
> > When writing one of those, my IDE (IntelliJ IDEA) gives me a warning
> > about an incompatible type assignment. writing it like I did doesn't.
>
> IDEA will give a warning for the former but not the latter (and it can infer the type).
>
Yes, you are right. But I really want it to be of type Cell. ;)

> >> Is Cell a plain, top-level interface?
> > Yes, it is :
> >https://github.com/karfau/graxle-table/blob/master/src/main/groovy/de...
> > and so is Matrix:
> >https://github.com/karfau/graxle-table/blob/master/src/main/groovy/de...
>
> You have to make Cell public. The error message isn't very clear on this, but it's nothing that we can easily improve.
>
Oh my god. (Mixing groovy and Java...)
It had been a groovy interface earlier and when converting it to a
java interface manually I forgot to at "public" to it. And as I don't
yet have anything outside the package that use the interface, I didn't
recognize.

Thx a lot for pointing me to this!

karfau

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/spockframework?hl=en.

Loading...