You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by "Eric J. Van der Velden" <er...@gmail.com> on 2017/01/12 09:22:55 UTC

Cannot mock final SortableDataProvider.getSortState

Hello,

SortableDataProvider, in
package org.apache.wicket.extensions.markup.html.repeater.util, has a final
method getSortState().

I cannot mock this method.

I have copied SortableDataProvider under a different name, and subclassed
this one,but I do not like this.

The same happens with final LoadableDetachableModel.getObject(), but in
this case I could mock LoadableDetachableModel.load().

So why are these methods final, and how do programmers test the provider?

Thank you!

Re: Cannot mock final SortableDataProvider.getSortState

Posted by "Eric J. Van der Velden" <er...@gmail.com>.
Hoi Bas,

I am at the office now, so now I would like to comment on the first
question in your last answer.

My experience is that when you mock a class, and you call a final method on
the mock, Mockito returns null. So it is not that you can trust a final
method or not, the mock's method returns null. Or maybe I make a mistake.

It happens in OrderByBorder.onComponentTag. This method calls the
provider's getSortState(), which will return null. That is why I wanted to
mock this method, but I cannot, because it is final.

Thanks, I will comment on your other remarks later.

On Fri, Jan 13, 2017 at 1:41 PM, Bas Gooren <ba...@iswd.nl> wrote:

> Hi Eric,
>
>
> Well - looking at SortableDataProvider I suppose you cold mock an
> implementation of it. As getSortState() is final, you need to trust that it
> does it’s job. Why do you want to mock that method?
>
> The same applies to LoadableDetachableModel - why do you need to mock
> final getObject(), which has a know contract/implementation?
>
>
> In general I’m not sure I understand yet why you are mocking your
> SortableContactDataProvider.
>
>
> If you want to test that your SortableContactDataProvider does it’s job
> properly, provide it with a mock database so you can verify that it makes
> all expected calls.
>
> Since you are using a static call to locate your database, you could
> introduce a way to force a ContactsDatabase for the current thread in your
> locator class.
>
>
> For example (pseudocode for a unit test):
>
>
> … run before test
>
> ContactsDatabase mockDatabase = createMock(…)
>
> DatabaseLocator.setDatabaseForCurrentThread(mockDatabase)
>
>
> … in test
>
> expect(mockDatabase.getIndex(anyObject())).andReturn(…)
>
> SortableContactDataProvider.iterator(….)
>
> etc.
>
>
> … run after test
>
> DatabaseLocator.clearDatabaseForCurrentThread()
>
> Met vriendelijke groet,
> Kind regards,
>
> Bas Gooren
>
> Op 13 januari 2017 bij 12:10:03, Eric J. Van der Velden (
> ericjvandervelden@gmail.com) schreef:
>
> Hoi Bas,
>
> Thank you for your answer!
>
> So maybe I am doing it wrong.
>
> Let's take an example. In the wicket examples, in package
> org.apache.wicket.examples.repeater, there is the provider:
>
> public class SortableContactDataProvider_my extends
> SortableDataProvider_my<Contact, String> implements IFilterStateLocator<
> ContactFilter_my>
> {
> ...
>
> protected ContactsDatabase getContactsDB()
> {
> return DatabaseLocator.getDatabase();
> }
>
> @Override
> public Iterator<Contact> iterator(long first, long count)
> {
> List<Contact> contactsFound = getContactsDB().getIndex(getSort());
> return filterContacts(contactsFound).
> subList((int)first, (int)(first + count)).
> iterator();
> }
>
> I mocked the iterator method. But you are saying that I should mock the
> getContactsDB method?
>
> Thank you.
>
> On Thu, Jan 12, 2017 at 11:10 AM, Bas Gooren <ba...@iswd.nl> wrote:
>
>> Eric,
>>
>>
>> All of our data providers use an external source to load the actual data,
>> e.g. a repository or dao.
>>
>> As all of our repositories and daos are interfaces, those are easy to
>> mock.
>>
>>
>> Testing the provider is then simply a matter of ensuring the right
>> methods, with the right parameters are called on the mocked objects.
>>
>>
>> What functionality in your (custom) data providers do you have that you
>> want to test? In general I would say that final methods in a known and
>> tested library (wicket) do not need to be tested anyway - that is the
>> responsibility of the library.
>>
>> Met vriendelijke groet,
>> Kind regards,
>>
>> Bas Gooren
>>
>> Op 12 januari 2017 bij 10:23:12, Eric J. Van der Velden (
>> ericjvandervelden@gmail.com) schreef:
>>
>> Hello,
>>
>> SortableDataProvider, in
>> package org.apache.wicket.extensions.markup.html.repeater.util, has a
>> final
>> method getSortState().
>>
>> I cannot mock this method.
>>
>> I have copied SortableDataProvider under a different name, and subclassed
>> this one,but I do not like this.
>>
>> The same happens with final LoadableDetachableModel.getObject(), but in
>> this case I could mock LoadableDetachableModel.load().
>>
>> So why are these methods final, and how do programmers test the provider?
>>
>> Thank you!
>>
>>
>

Re: Cannot mock final SortableDataProvider.getSortState

Posted by Bas Gooren <ba...@iswd.nl>.
Hi Eric,


Well - looking at SortableDataProvider I suppose you cold mock an
implementation of it. As getSortState() is final, you need to trust that it
does it’s job. Why do you want to mock that method?

The same applies to LoadableDetachableModel - why do you need to mock final
getObject(), which has a know contract/implementation?


In general I’m not sure I understand yet why you are mocking your
SortableContactDataProvider.


If you want to test that your SortableContactDataProvider does it’s job
properly, provide it with a mock database so you can verify that it makes
all expected calls.

Since you are using a static call to locate your database, you could
introduce a way to force a ContactsDatabase for the current thread in your
locator class.


For example (pseudocode for a unit test):


… run before test

ContactsDatabase mockDatabase = createMock(…)

DatabaseLocator.setDatabaseForCurrentThread(mockDatabase)


… in test

expect(mockDatabase.getIndex(anyObject())).andReturn(…)

SortableContactDataProvider.iterator(….)

etc.


… run after test

DatabaseLocator.clearDatabaseForCurrentThread()

Met vriendelijke groet,
Kind regards,

Bas Gooren

Op 13 januari 2017 bij 12:10:03, Eric J. Van der Velden (
ericjvandervelden@gmail.com) schreef:

Hoi Bas,

Thank you for your answer!

So maybe I am doing it wrong.

Let's take an example. In the wicket examples, in package
org.apache.wicket.examples.repeater, there is the provider:

public class SortableContactDataProvider_my extends
SortableDataProvider_my<Contact, String> implements
IFilterStateLocator<ContactFilter_my>
{
...

protected ContactsDatabase getContactsDB()
{
return DatabaseLocator.getDatabase();
}

@Override
public Iterator<Contact> iterator(long first, long count)
{
List<Contact> contactsFound = getContactsDB().getIndex(getSort());
return filterContacts(contactsFound).
subList((int)first, (int)(first + count)).
iterator();
}

I mocked the iterator method. But you are saying that I should mock the
getContactsDB method?

Thank you.

On Thu, Jan 12, 2017 at 11:10 AM, Bas Gooren <ba...@iswd.nl> wrote:

> Eric,
>
>
> All of our data providers use an external source to load the actual data,
> e.g. a repository or dao.
>
> As all of our repositories and daos are interfaces, those are easy to mock.
>
>
> Testing the provider is then simply a matter of ensuring the right
> methods, with the right parameters are called on the mocked objects.
>
>
> What functionality in your (custom) data providers do you have that you
> want to test? In general I would say that final methods in a known and
> tested library (wicket) do not need to be tested anyway - that is the
> responsibility of the library.
>
> Met vriendelijke groet,
> Kind regards,
>
> Bas Gooren
>
> Op 12 januari 2017 bij 10:23:12, Eric J. Van der Velden (
> ericjvandervelden@gmail.com) schreef:
>
> Hello,
>
> SortableDataProvider, in
> package org.apache.wicket.extensions.markup.html.repeater.util, has a
> final
> method getSortState().
>
> I cannot mock this method.
>
> I have copied SortableDataProvider under a different name, and subclassed
> this one,but I do not like this.
>
> The same happens with final LoadableDetachableModel.getObject(), but in
> this case I could mock LoadableDetachableModel.load().
>
> So why are these methods final, and how do programmers test the provider?
>
> Thank you!
>
>

Re: Cannot mock final SortableDataProvider.getSortState

Posted by "Eric J. Van der Velden" <er...@gmail.com>.
Hoi Bas,

Thank you for your answer!

So maybe I am doing it wrong.

Let's take an example. In the wicket examples, in package
org.apache.wicket.examples.repeater, there is the provider:

public class SortableContactDataProvider_my extends
SortableDataProvider_my<Contact, String> implements
IFilterStateLocator<ContactFilter_my>
{
...

protected ContactsDatabase getContactsDB()
{
return DatabaseLocator.getDatabase();
}

@Override
public Iterator<Contact> iterator(long first, long count)
{
List<Contact> contactsFound = getContactsDB().getIndex(getSort());
return filterContacts(contactsFound).
subList((int)first, (int)(first + count)).
iterator();
}

I mocked the iterator method. But you are saying that I should mock the
getContactsDB method?

Thank you.

On Thu, Jan 12, 2017 at 11:10 AM, Bas Gooren <ba...@iswd.nl> wrote:

> Eric,
>
>
> All of our data providers use an external source to load the actual data,
> e.g. a repository or dao.
>
> As all of our repositories and daos are interfaces, those are easy to mock.
>
>
> Testing the provider is then simply a matter of ensuring the right
> methods, with the right parameters are called on the mocked objects.
>
>
> What functionality in your (custom) data providers do you have that you
> want to test? In general I would say that final methods in a known and
> tested library (wicket) do not need to be tested anyway - that is the
> responsibility of the library.
>
> Met vriendelijke groet,
> Kind regards,
>
> Bas Gooren
>
> Op 12 januari 2017 bij 10:23:12, Eric J. Van der Velden (
> ericjvandervelden@gmail.com) schreef:
>
> Hello,
>
> SortableDataProvider, in
> package org.apache.wicket.extensions.markup.html.repeater.util, has a
> final
> method getSortState().
>
> I cannot mock this method.
>
> I have copied SortableDataProvider under a different name, and subclassed
> this one,but I do not like this.
>
> The same happens with final LoadableDetachableModel.getObject(), but in
> this case I could mock LoadableDetachableModel.load().
>
> So why are these methods final, and how do programmers test the provider?
>
> Thank you!
>
>

Re: Cannot mock final SortableDataProvider.getSortState

Posted by Bas Gooren <ba...@iswd.nl>.
Eric,


All of our data providers use an external source to load the actual data,
e.g. a repository or dao.

As all of our repositories and daos are interfaces, those are easy to mock.


Testing the provider is then simply a matter of ensuring the right methods,
with the right parameters are called on the mocked objects.


What functionality in your (custom) data providers do you have that you
want to test? In general I would say that final methods in a known and
tested library (wicket) do not need to be tested anyway - that is the
responsibility of the library.

Met vriendelijke groet,
Kind regards,

Bas Gooren

Op 12 januari 2017 bij 10:23:12, Eric J. Van der Velden (
ericjvandervelden@gmail.com) schreef:

Hello,

SortableDataProvider, in
package org.apache.wicket.extensions.markup.html.repeater.util, has a final
method getSortState().

I cannot mock this method.

I have copied SortableDataProvider under a different name, and subclassed
this one,but I do not like this.

The same happens with final LoadableDetachableModel.getObject(), but in
this case I could mock LoadableDetachableModel.load().

So why are these methods final, and how do programmers test the provider?

Thank you!