active-record icon indicating copy to clipboard operation
active-record copied to clipboard

UnqueryableQueryMock::all() returns Exception but 0 count is expected

Open fcaldarelli opened this issue 6 years ago • 14 comments

https://github.com/yiisoft/active-record/blob/bed8118208835fd4bf6081e6e24f9c36f449b7cd/tests/unit/ActiveDataProviderTest.php#L193

Here we expect that count is 0. But UnqueryableQueryMock::all() returns an Exception mandatory.

https://github.com/FabrizioCaldarelli/db/blob/b1bb19a4bafbe5a84aa62388cd3f0e81b5db809f/tests/unit/UnqueryableQueryMock.php#L28

fcaldarelli avatar Feb 06 '19 22:02 fcaldarelli

I found the problem, it is about how prepareModels() has changed.

In current ActiveDataProvider version, prepareModels() calls prepareQuery(). When there are not records, $query->emulateExecution(); is called and anyway the methods returns $query object.

https://github.com/yiisoft/active-record/blob/bed8118208835fd4bf6081e6e24f9c36f449b7cd/src/data/ActiveDataProvider.php#L122

In previous implementation, prepareModels() returned an empty array where there are not records:

https://github.com/yiisoft/active-record/blob/e93f97cd0cee1f23e217d4d32b2a88f8fab52b3a/src/data/ActiveDataProvider.php#L111

This is from last commit, where @GHopperMSK wanted to explicit $query content to simplify debug activities.

https://github.com/yiisoft/active-record/commit/bed8118208835fd4bf6081e6e24f9c36f449b7cd

We can solve checking emulateExecution property that it has been used to track this case, from last commit:

    protected function prepareModels()
    {
        $query = $this->prepareQuery();
        return ($query->emulateExecution) ? [] : $query->all($this->db);
    }

fcaldarelli avatar Feb 07 '19 00:02 fcaldarelli

I don't think it is a good idea to return an empty array. Now we return $query object and it is quite convenient in all cases. If the query is empty, it sets emulate mode witch protects the DB from unnecessary requests. If the query isn't empty, it works as usual. We don't need to check the results every time, we just work with obtained object.

Maybe we should just adapt the test to new conditions?

np25071984 avatar Feb 07 '19 08:02 np25071984

I don't think it is a good idea to return an empty array. Now we return $query object and it is

In previous implementation, prepareModels() did the same work that you now do with two methods, so it made sense that it returned an empty array, in that condition.

fcaldarelli avatar Feb 07 '19 09:02 fcaldarelli

In previous implementation, prepareModels() did the same work that you now do with two methods

If so, then how test $this->assertCount(0, $provider->getModels()); passed successfully?

np25071984 avatar Feb 07 '19 09:02 np25071984

I have explained in previous post, because prepareModels() returned an empty array:

https://github.com/yiisoft/active-record/blob/e93f97cd0cee1f23e217d4d32b2a88f8fab52b3a/src/data/ActiveDataProvider.php#L111

and test succeded.

fcaldarelli avatar Feb 07 '19 09:02 fcaldarelli

This should be fixed in UnqueryableQueryMock - it should not throw exception if emulateExecution is enabled.

rob006 avatar Feb 07 '19 10:02 rob006

In this case it is not about emulateExecution , because it has been added from last commit.

UnqueryableQueryMock throw an exception independently from emulateExecution.

fcaldarelli avatar Feb 07 '19 11:02 fcaldarelli

UnqueryableQueryMock throw an exception independently from emulateExecution.

Yes, and that is the problem.

rob006 avatar Feb 07 '19 11:02 rob006

Yes, and that is the problem.

Why? In previous release it worked fine, because as class name says it has to test query not queryable.

fcaldarelli avatar Feb 07 '19 11:02 fcaldarelli

The purpose of this mock is to ensure that no actual query will be performed. With emulateExecution there will be not actual query, there should be no exception in this case.

rob006 avatar Feb 07 '19 11:02 rob006

Take a look at differences from last commit (not working) and previous (working).

fcaldarelli avatar Feb 07 '19 11:02 fcaldarelli

@FabrizioCaldarelli I don't get your point. These changes are correct, the tests should be fixed to not throw exception when there is no need for it. It was already done in https://github.com/yiisoft/yii2/pull/17073

rob006 avatar Feb 07 '19 11:02 rob006

I showed how keep current tests and current changes together.

fcaldarelli avatar Feb 07 '19 11:02 fcaldarelli

Why would you want add additional conditions to (correct) code instead of fixing (incorrect) tests? It is actually a bug that UnqueryableQueryMock throws exception for query with emulateExecution, it should be changed anyway.

rob006 avatar Feb 07 '19 11:02 rob006