I am trying to test a sub query using SOQL Lib

In the docs it says will ignore all filters and relations so how is this possible if I cannot create a relationship?

My example is to get all opportunities for an Account who's amount value is between 500 and 2,000

Account Selector

 public AccountSelector getOpportunitiesByAmount(Id account_id){
        .with(Opportunity.Id, Opportunity.Amount)
            .conditionLogic('1 AND 2')

    return this;

Controller The debug is to make sure that the expected result works which is does

    public static List<Account> getOpportunitiesInAccount(String account_id) {  
    // making sure it works      
    List<Account> accList = AccountSelector.query()
    Opportunity opps = accList[0].Opportunities;
    return AccountSelector.query()


At the moment I am getting the error - System.QueryException: List has no rows for assignment to SObject

static void opportunityForAccountInRange(){ 

    List<Opportunity> opportunity_list = new List<Opportunity>{
        new Opportunity(AccountId = '0012o00003ORxRcAAL', Amount = 500),
        new Opportunity(AccountId = '0012o00003ORxRcAAL', Amount = 1500),
        new Opportunity(AccountId = '0012o00003ORxRcAAL', Amount = 2000)
    SOQL.setMock('AccountController.getOpportunitiesInAccount', opportunity_list);

    Account account_for_test = new Account(Id = '0012o00003ORxRcAAL', Name = 'Test');
    SOQL.setMock('AccountController.getOpportunitiesInAccount', account_for_test);

    List<Account> result = AccountController.getOpportunitiesInAccount('0012o00003ORxRcAAL');

    // Opportunity opps = result[0].Opportunities;
    // System.debug(opps.Amount);
    Assert.areEqual(1, result.size());

I was hoping that if anyone has experience using SOQL Lib if they could help shed some light around testing sub queries.

1 Answer 1


To test sub-queries you should use the deserialization mechanism with JSON data (to write on non-writable fields), as described in the documentation:


To mock a sub-query we need to use deserialization mechanism. There are two approaches, using JSON string or Serialization/Deserialization. Then after deserialization to desired SObjectType, pass the data to SOQL by calling .setMock method.

Using JSON String

By passing simple String, it is possible to write non-writable fields, like Name on Contact object.

static void getAccountsWithContacts() {
   List<Account> mocks = (List<Account>) JSON.deserialize(
       '[{ "Name": "Account Name", "Contacts": { "totalSize": 1, "done": true, "records": [{ "Name": "Contact Name", "Email": "[email protected]" }] }  }],

   List<Account> accounts;

   SOQL.setMock('AccountsController.getAccountsWithContacts', mocks);
   accounts = AccountsController.getAccountsWithContacts();

   Assert.areEqual(1, accounts[0].contacts.size());

I suggest reading the documentation on this because it also explains how to use the JSON.serialize method to build the mocked data with lists and maps instead of a single string.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .