Mocking Paginator #5236

Closed
opened 2026-01-22 15:02:12 +01:00 by admin · 12 comments
Owner

Originally created by @matiux on GitHub (Aug 31, 2016).

Hi,
I need to test a service that accepts a Doctrine\ORM\Tools\Pagination\Paginator object.
I wouldn't use the real repository in the test class. Rather I'd like to mock Paginator with some result so that I can pass it to my service.

I'm looking for the examples in the source code but I still not find them.

Can someone supply some examples to mock Paginator?

Thanks

Originally created by @matiux on GitHub (Aug 31, 2016). Hi, I need to test a service that accepts a `Doctrine\ORM\Tools\Pagination\Paginator` object. I wouldn't use the real repository in the test class. Rather I'd like to mock Paginator with some result so that I can pass it to my service. I'm looking for the examples in the source code but I still not find them. Can someone supply some examples to mock Paginator? Thanks
admin closed this issue 2026-01-22 15:02:13 +01:00
Author
Owner

@Ocramius commented on GitHub (Aug 31, 2016):

A Paginator is just an iterator: you can type-hint against that, usually.

On 31 Aug 2016 1:19 p.m., "Matteo" notifications@github.com wrote:

Hi,
I need to test a service that accepts a Doctrine\ORM\Tools\Pagination
Paginator object.
I wouldn't use the real repository in the test class. Rather I'd like to
mock Paginator with some result so that I can pass it to my service.

I'm looking for the examples in the source code but I still not find them.

Can someone supply some examples to mock Paginator?

Thanks


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/5999, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJakNIX3APfF5qq79NVrlFWJ96qdbVfks5qlWNPgaJpZM4JxgBy
.

@Ocramius commented on GitHub (Aug 31, 2016): A Paginator is just an iterator: you can type-hint against that, usually. On 31 Aug 2016 1:19 p.m., "Matteo" notifications@github.com wrote: > Hi, > I need to test a service that accepts a Doctrine\ORM\Tools\Pagination\ > Paginator object. > I wouldn't use the real repository in the test class. Rather I'd like to > mock Paginator with some result so that I can pass it to my service. > > I'm looking for the examples in the source code but I still not find them. > > Can someone supply some examples to mock Paginator? > > Thanks > > — > You are receiving this because you are subscribed to this thread. > Reply to this email directly, view it on GitHub > https://github.com/doctrine/doctrine2/issues/5999, or mute the thread > https://github.com/notifications/unsubscribe-auth/AAJakNIX3APfF5qq79NVrlFWJ96qdbVfks5qlWNPgaJpZM4JxgBy > .
Author
Owner

@matiux commented on GitHub (Aug 31, 2016):

Thanks @Ocramius,
what do you mean with "type-hint against that" ?

@matiux commented on GitHub (Aug 31, 2016): Thanks @Ocramius, what do you mean with "type-hint against that" ?
Author
Owner

@lcobucci commented on GitHub (Aug 31, 2016):

Paginator implements IteratorAggregate (that extends Traversable). So you can use Traversable as type-hint and pass any iterator you want (instead of mocking Paginator class).

@lcobucci commented on GitHub (Aug 31, 2016): `Paginator` implements `IteratorAggregate` (that extends `Traversable`). So you can use `Traversable` as type-hint and pass any iterator you want (instead of mocking `Paginator` class).
Author
Owner

@matiux commented on GitHub (Aug 31, 2016):

Thanks,
I'm was also able to create a mock:

$config = m::mock(Configuration::class);
$config->shouldReceive('getDefaultQueryHints')->andReturn([]);
$config->shouldReceive('isSecondLevelCacheEnabled')->andReturn(false);

$em = m::mock(EntityManager::class);
$em->shouldReceive('getConfiguration')->andReturn($config);

$query = m::mock(new Query($em));
$query->shouldReceive('getFirstResult')->andReturn(1);

$paginator = m::namedMock('Paginator', 'Doctrine\ORM\Tools\Pagination\Paginator');
$paginator->shouldReceive('count')->atMost(1)->andReturn(count($results));
$paginator->shouldReceive('getQuery')->atMost(1)->andReturn($query);
$paginator->shouldReceive('getIterator')->atMost(1)->andReturn(new \ArrayIterator($results));

adding the methods that I need

@matiux commented on GitHub (Aug 31, 2016): Thanks, I'm was also able to create a mock: ``` $config = m::mock(Configuration::class); $config->shouldReceive('getDefaultQueryHints')->andReturn([]); $config->shouldReceive('isSecondLevelCacheEnabled')->andReturn(false); $em = m::mock(EntityManager::class); $em->shouldReceive('getConfiguration')->andReturn($config); $query = m::mock(new Query($em)); $query->shouldReceive('getFirstResult')->andReturn(1); $paginator = m::namedMock('Paginator', 'Doctrine\ORM\Tools\Pagination\Paginator'); $paginator->shouldReceive('count')->atMost(1)->andReturn(count($results)); $paginator->shouldReceive('getQuery')->atMost(1)->andReturn($query); $paginator->shouldReceive('getIterator')->atMost(1)->andReturn(new \ArrayIterator($results)); ``` adding the methods that I need
Author
Owner

@Ocramius commented on GitHub (Sep 1, 2016):

That is all waaaaaay too specific mocking of implementation details. Refrain from doing that: it is just making your tests fragile, hard to read and an overall no-value-added.

See what @lcobucci said instead.

Closing here: thought it was on the mailing list, but it's on the tracker, and the tracker is for issues ;-)

@Ocramius commented on GitHub (Sep 1, 2016): That is all waaaaaay too specific mocking of implementation details. Refrain from doing that: it is just making your tests fragile, hard to read and an overall no-value-added. See what @lcobucci said instead. Closing here: thought it was on the mailing list, but it's on the tracker, and the tracker is for issues ;-)
Author
Owner

@matiux commented on GitHub (Sep 1, 2016):

I have a doubt. Using Traversable object, how can I have, for example getFirstResult() method? My service (that accepts Paginator object), needs to access to Query in Paginator to get the first result

Thanks

@matiux commented on GitHub (Sep 1, 2016): I have a doubt. Using Traversable object, how can I have, for example `getFirstResult()` method? My service (that accepts `Paginator` object), needs to access to `Query` in `Paginator` to get the first result Thanks
Author
Owner

@Ocramius commented on GitHub (Sep 1, 2016):

You'd inject the query and the paginator separately then. Getting the query from the paginator is usually a bad idea...

@Ocramius commented on GitHub (Sep 1, 2016): You'd inject the query and the paginator separately then. Getting the query from the paginator is usually a bad idea...
Author
Owner

@matiux commented on GitHub (Sep 1, 2016):

Paginator is based on the query. You can simply get the query with $paginator->getQuery(). Passing Paginator and Query separately is a redundant way. My 2 cents.

public function foo(Paginator $p, Query $q) {
}

public function foo(Paginator $p) {

$q = $p->getQuery();
}

I don't think that the second approach it's wrong :)

@matiux commented on GitHub (Sep 1, 2016): Paginator is based on the query. You can simply get the query with `$paginator->getQuery()`. Passing Paginator and Query separately is a redundant way. My 2 cents. ``` public function foo(Paginator $p, Query $q) { } public function foo(Paginator $p) { $q = $p->getQuery(); } ``` I don't think that the second approach it's wrong :)
Author
Owner

@Ocramius commented on GitHub (Sep 1, 2016):

The second approach is wrong because you are assuming that the query that
you retrieve is the same one you gave in. No guarantee on this comes from
that API.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On Thu, Sep 1, 2016 at 11:06 AM, Matteo notifications@github.com wrote:

Paginator is based on the query. You can simply get the query with
$paginator->getQuery(). Passing Paginator and Query separately is a
redundant way. My 2 cents.

public function foo(Paginator $p, Query $q) {
}

public function foo(Paginator $p) {

$q = $p->getQuery();
}

I don't think that the second approach it's wrong :)


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/5999#issuecomment-244020635,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJakDRM08NXK2_Pb-FSX53apVq94KPmks5qlpWggaJpZM4JxgBy
.

@Ocramius commented on GitHub (Sep 1, 2016): The second approach is wrong because you are assuming that the query that you retrieve is the same one you gave in. No guarantee on this comes from that API. Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ On Thu, Sep 1, 2016 at 11:06 AM, Matteo notifications@github.com wrote: > Paginator is based on the query. You can simply get the query with > $paginator->getQuery(). Passing Paginator and Query separately is a > redundant way. My 2 cents. > > public function foo(Paginator $p, Query $q) { > } > > public function foo(Paginator $p) { > > $q = $p->getQuery(); > } > > I don't think that the second approach it's wrong :) > > — > You are receiving this because you modified the open/close state. > Reply to this email directly, view it on GitHub > https://github.com/doctrine/doctrine2/issues/5999#issuecomment-244020635, > or mute the thread > https://github.com/notifications/unsubscribe-auth/AAJakDRM08NXK2_Pb-FSX53apVq94KPmks5qlpWggaJpZM4JxgBy > .
Author
Owner

@matiux commented on GitHub (Sep 1, 2016):

According to this logic, from the repository I need to return not only Doctrine\ORM\Tools\Pagination\Paginator but also Doctrine\ORM\Query

@matiux commented on GitHub (Sep 1, 2016): According to this logic, from the repository I need to return not only `Doctrine\ORM\Tools\Pagination\Paginator` but also `Doctrine\ORM\Query`
Author
Owner

@Ocramius commented on GitHub (Sep 1, 2016):

Or just the iterator. If you want the first result only, you can traverse
the operator only to its first element. Throwing a query object around is
mostly trouble.

On 1 Sep 2016 11:13, "Matteo" notifications@github.com wrote:

According to this logic, from the repository I need to return non only
Doctrine\ORM\Tools\Pagination\Paginator but also Doctrine\ORM\Query


You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/5999#issuecomment-244022257,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJakKpm4VOJSc1tj7BoLonBgnQwXqIyks5qlpc1gaJpZM4JxgBy
.

@Ocramius commented on GitHub (Sep 1, 2016): Or just the iterator. If you want the first result only, you can traverse the operator only to its first element. Throwing a query object around is mostly trouble. On 1 Sep 2016 11:13, "Matteo" notifications@github.com wrote: > According to this logic, from the repository I need to return non only > Doctrine\ORM\Tools\Pagination\Paginator but also Doctrine\ORM\Query > > — > You are receiving this because you modified the open/close state. > Reply to this email directly, view it on GitHub > https://github.com/doctrine/doctrine2/issues/5999#issuecomment-244022257, > or mute the thread > https://github.com/notifications/unsubscribe-auth/AAJakKpm4VOJSc1tj7BoLonBgnQwXqIyks5qlpc1gaJpZM4JxgBy > .
Author
Owner

@matiux commented on GitHub (Sep 1, 2016):

There is a mistake. getFirstResult() doesn't return the first item of the collection. It returns the offset of the query.

... LIMIT 40 OFFSET 81

It is the parameter that you can set in the query doctrine with $queryBuilder->setFirstResult($offset);

This paramater there isn't in the Paginator object

@matiux commented on GitHub (Sep 1, 2016): There is a mistake. `getFirstResult()` doesn't return the first item of the collection. It returns the offset of the query. ... LIMIT 40 OFFSET **81** It is the parameter that you can set in the query doctrine with `$queryBuilder->setFirstResult($offset);` This paramater there isn't in the `Paginator` object
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5236