Re: [mockito] JDBC testing - attempting to make two statement calls on one Connection

1,102 views
Skip to first unread message

Sergey Kabashnyuk

unread,
Jun 11, 2012, 6:08:15 AM6/11/12
to moc...@googlegroups.com
Hello

You can return http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/stubbing/Answer.html
what will answer mockStatement1 at first time and mockStatement2 after.

Sergey Kabashnyuk


2012/6/10 Michael Nishizawa <mic...@nishizawas.net>:
> I am working on some functionality where I need to extend a proprietary
> software and, due to it's design I need to execute two queries on the
> particular request I am trying to make.  I have 1 mocked connection and I
> was expecting that I could do a simple matcher so the right statement would
> be returned based on the different sql strings.  So given two queries sql1
> and sql2:
>
> java.sql.Connection connection = mock(Connection.class);
> java.sql.PreparedStatement mockStatement1 = mock(PreparedStatement.class);
> java.sql.PreparedStatement mockStatement2 = mock(PreparedStatement.class);
>
> when(connection.prepareStatement(sql1).thenReturn(mockStatement1);
> when(connection.prepareStatement(sql2).thenReturn(mockStatement2);
>
> When I execute this, I end up with it working for the first one but not the
> second.  Is it true that this is the expected behavior and, if so, any ideas
> as to why it isn't working?  There is a trailing space on sql2 that is in
> the proprietary code that I can't change without more backflips than I
> really want to do if I don't have to.  However, I don't think that's the
> problem since I have tried with several variations of that in my verify
> statements to no avail.
>
> I also tried to spy it but apparently that does not work since the call to
> the stubbed method is made internally using a concept similar to the
> ServiceLocator pattern.
>
> To give you an idea of the class hierarcy, I have classes A and B where B
> where A is the class from the proprietary software product and B is the code
> we are using to extend A.  In my test I call
>
> B b = new B();
> b.findBees();
>
> findBees has something like:
>
> public List findBees() {
>     List output = getAllAs();  // this comes from the superclass(A)
>     output.addAll(database.getAllBees());
> }
>
> So in my efforts to spy it, I tried to do:
> B b = spy(new B());
> Mockito.when(b.getAllAs()).thenReturn(dataList);
>
> However, that invocation is not intercepted.
>
> Basically, I believe I need one or both of those to work in order to test
> this to the extent that I want.  It would be great if someone could explain
> to me how to do this in Mockito or show me a different way.
>
> Thanks for your help in advance!
>
> --
> You received this message because you are subscribed to the Google Groups
> "mockito" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/mockito/-/JGKlL5ILJSIJ.
> To post to this group, send email to moc...@googlegroups.com.
> To unsubscribe from this group, send email to
> mockito+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/mockito?hl=en.

Eric Lefevre-Ardant

unread,
Jun 11, 2012, 6:09:39 AM6/11/12
to moc...@googlegroups.com
I think the problem is that you cannot spy calls from within the instance you want to spy.

In other words:
  • you create an instance b
  • you can a mock to this instance, spyB
  • you call spyB.findBees()
  • spyB.findBees() calls b.findBees(), as its default behavior
  • internally, b.findBees() calls b.getAllAs()
b has no knowledge of spyB, so there is no way it would call the mocked version of spyB.getAllAs()

If you can, you should turn A into an attribute of B, not a parent.

Szczepan Faber

unread,
Jun 11, 2012, 8:54:53 AM6/11/12
to moc...@googlegroups.com
I think the problem is that you cannot spy calls from within the instance you want to spy.

You  should be able to that unless the method unless the method is final/package protected in parent.
 
In other words:
  • you create an instance b
  • you can a mock to this instance, spyB
  • you call spyB.findBees()
  • spyB.findBees() calls b.findBees(), as its default behavior
  • internally, b.findBees() calls b.getAllAs()
b has no knowledge of spyB, so there is no way it would call the mocked version of spyB.getAllAs()

If you can, you should turn A into an attribute of B, not a parent.

Good advice! I'm sure you can refactor the code to make testing easier :)

Cheers!



--
Szczepan Faber
Principal engineer@gradleware
Lead@mockito

Michael Nishizawa

unread,
Jul 20, 2012, 2:57:12 PM7/20/12
to mockito
That worked, thanks Eric.

On Jun 11, 6:09 am, Eric Lefevre-Ardant <e...@ericlefevre.net> wrote:
> I think the problem is that you cannot spy calls from within the instance
> you want to spy.
>
> In other words:
>
>    - you create an instance b
>    - you can a mock to this instance, spyB
>    - you call spyB.findBees()
>    - spyB.findBees() calls b.findBees(), as its default behavior
>    - internally, b.findBees() calls b.getAllAs()
>
> b has no knowledge of spyB, so there is no way it would call the mocked
> version of spyB.getAllAs()
>
> If you can, you should turn A into an attribute of B, not a parent.
>
> On 10 June 2012 08:09, Michael Nishizawa <mich...@nishizawas.net> wrote:> I am working on some functionality where I need to extend a proprietary
Reply all
Reply to author
Forward
0 new messages