11

I wrote a class that needs to query for "cases owned by the current user or in a queue", and so I wrote this seemingly normal query:

Case[] cases = [SELECT Id 
                FROM   Case 
                WHERE  IsClosed = false AND 
                       Id = :controller.getSelected() AND
                      (OwnerId = :UserInfo.getUserId() OR Owner.Type = 'Queue')];

This worked when I tested it in the UI, but when I went to write a unit test, I ended up retrieving zero rows, which prompted an assertion:

System.assertEquals(1, cmcc.getCaseCloseCount());

To fail with "Expected: 1, Actual: 0."

Mildly perplexed, I took out OR Owner.Type = 'Queue' and it worked as expected. Thinking this might just be a one-off situation, I wrote a separate unit test to verify the behavior:

@isTest class queueFailTest {
    @isTest static void test() {
        Group g = new Group(Name='TestQueue',Type='Queue');
        System.runas(new User(Id=UserInfo.getUserId())) {
            insert g;
            insert new QueueSobject(QueueId=g.id, SObjectType='Lead');
        }
        insert new lead(lastname='test',company='test');
        insert new lead(lastname='testqueue',company='testqueue',ownerid=g.Id);
        lead[] record1 = [select id from lead where ownerid = :userinfo.getuserid()];
        lead[] record2 = [select id from lead where owner.type = 'queue'];
        lead[] record3 = [select id from lead where (ownerid = :userinfo.getuserid() or owner.type='queue')];
        System.assertEquals(1, record1.size());
        System.assertEquals(1, record2.size());
        System.assertEquals(2, record3.size()); // Expected: 2, Actual: 1
    }
}

This fails on line 15 as noted above (Expected: 2, Actual: 1), leading me to believe that Owner.Type = 'Queue' is somehow causing the OwnerId filter to be ignored despite being an OR filter.

Can anyone else confirm this behavior? Is this a Known Issue? Is there an alternative way of doing this query with just one query, and not two, just for the sake of unit tests?

Note: All three queries work normally in Execute Anonymous and normal SOQL (e.g. Data Loader) queries. It fails in unit tests regardless of SeeAllData being true or false (my org has no leads in it, as it's just an empty Developer Edition).

  • Haven’t tried anything yet but this seems to be yet another mysterious case of test classes. I have seen at least two different posts around content notes behavior in test classes. – Jayant Das Aug 31 '18 at 2:23
  • 1
    It might be just typo but in record3 filter criteria , you are comparing owner.name with userId. – javanoob Aug 31 '18 at 2:51
  • @javanoob yes, the original query was filtering by name. The outcome is the same, however. I've edited this to remove any possible confusion, though. – sfdcfox Aug 31 '18 at 3:05
  • Just for kicks, do you know which one of them you’re finding? And does this behavior change if you invert the order of The OR clause? – Sebastian Kessel Aug 31 '18 at 5:21
  • 1
    @SebastianKessel Yes, through experimentation (this isn't the only version I wrote), the ownerid is ignored if owner.type is specified. The order of filters doesn't matter, if both are specified, the ownerid is ignored in favor of owner.type. – sfdcfox Aug 31 '18 at 5:25
2

Is there an alternative way of doing this query with just one query, and not two, just for the sake of unit tests?

As a trusty and time tested pattern for getting around SOQL Limitations, I would use a formula here:

OR(OwnerId = $User.Id, Owner.Type = "Queue")

And then you can just change your filter to:

WHERE IsOwnedByMeOrQueue__c = true
| improve this answer | |
  • +1 from before, but ultimately that would have caused non-selective query issues, so we finally just settled for only checking for the working data type. At least Premier Support admitted it was a bug. – sfdcfox Nov 9 '18 at 15:55
0

Following up on this question, case 19976168 was submitted for review. It was confirmed by Tier III, and a bug was submitted, although no bug number was given. The workaround they proposed was to use SeeAllData=true for the unit tests, but this didn't work for us, as per the original question.

This will probably be fixed at some point in the future. For now, the solution we used to was to only test for a Queue record. The unit test is slightly inaccurate, but at least it allowed us to get the code in to production without the inefficiency of the unit test holding us back.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.