Skip to content

Commit 186f403

Browse files
committed
[166-cannot-mock-queries-selecting-non-writeable-fields-in-500]
Signed-off-by: Piotr PG Gajek <[email protected]>
1 parent 36625e4 commit 186f403

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

force-app/main/default/classes/main/standard-soql/SOQL.cls

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2159,22 +2159,29 @@ public virtual inherited sharing class SOQL implements Queryable {
21592159
}
21602160

21612161
if (fields.relationshipFields.isEmpty() && fields.functionsFields.isEmpty()) {
2162-
this.stripAdditionalPlainFields(fields.plainFields.get());
2162+
this.mockedRecords = this.stripAdditionalPlainFields(fields.plainFields.get());
21632163
}
21642164

21652165
return this.mockedRecords;
21662166
}
21672167

2168-
private void stripAdditionalPlainFields(Set<String> requestedFields) {
2169-
for (SObject record : this.mockedRecords) {
2170-
Map<String, Object> fieldsToValue = record.getPopulatedFieldsAsMap();
2168+
private List<SObject> stripAdditionalPlainFields(Set<String> requestedFields) {
2169+
List<SObject> cleanedRecords = new List<SObject>();
2170+
Type objectTypeName = Type.forName(this.mockedRecords[0].getSObjectType().toString());
21712171

2172-
record.clear();
2172+
for (SObject record : this.mockedRecords) {
2173+
Map<String, Object> originalFields = record.getPopulatedFieldsAsMap();
2174+
Map<String, Object> filteredFields = new Map<String, Object>();
21732175

21742176
for (String field : requestedFields) {
2175-
record.put(field, fieldsToValue.get(field));
2177+
filteredFields.put(field, originalFields.get(field) ?? null);
21762178
}
2179+
2180+
// JSON.serialize and JSON.deserialize are used to copy not writtable fields
2181+
cleanedRecords.add((SObject) JSON.deserialize(JSON.serialize(filteredFields), objectTypeName));
21772182
}
2183+
2184+
return cleanedRecords;
21782185
}
21792186
}
21802187

force-app/main/default/classes/main/standard-soql/SOQL_Test.cls

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3250,7 +3250,7 @@ private class SOQL_Test {
32503250

32513251
// Test
32523252
SOQL.setMock('mockingQuery', accounts);
3253-
List<Account> result = SOQL.of(Account.SObjectType).mockId('mockingQuery').toList();
3253+
List<Account> result = SOQL.of(Account.SObjectType).with(Account.Name).mockId('mockingQuery').toList();
32543254

32553255
// Verify
32563256
Assert.areEqual(accounts, result, 'The mocked accounts should be returned.');
@@ -3263,7 +3263,7 @@ private class SOQL_Test {
32633263

32643264
// Test
32653265
SOQL.setMock('mockingQuery', testAccount);
3266-
Account result = (Account) SOQL.of(Account.sObjectType).mockId('mockingQuery').toObject();
3266+
Account result = (Account) SOQL.of(Account.sObjectType).with(Account.Name).mockId('mockingQuery').toObject();
32673267

32683268
// Verify
32693269
Assert.areEqual(testAccount, result, 'The mocked account should be returned.');
@@ -3278,7 +3278,7 @@ private class SOQL_Test {
32783278

32793279
// Test
32803280
SOQL.setMock('mockingQuery', testAccounts);
3281-
List<Account> result = SOQL.of(Account.sObjectType).mockId('mockingQuery').toList();
3281+
List<Account> result = SOQL.of(Account.sObjectType).with(Account.Name).mockId('mockingQuery').toList();
32823282

32833283
// Verify
32843284
Assert.areEqual(testAccounts, result, 'The mocked accounts should be returned.');
@@ -3291,7 +3291,7 @@ private class SOQL_Test {
32913291

32923292
// Test
32933293
SOQL.mock('mockingQuery').thenReturn(testAccount);
3294-
Account result = (Account) SOQL.of(Account.sObjectType).mockId('mockingQuery').toObject();
3294+
Account result = (Account) SOQL.of(Account.sObjectType).with(Account.Name).mockId('mockingQuery').toObject();
32953295

32963296
// Verify
32973297
Assert.areEqual(testAccount, result, 'The mocked account should be returned.');
@@ -3334,13 +3334,13 @@ private class SOQL_Test {
33343334

33353335
for (Account mockedResult : result) {
33363336
Assert.isTrue(mockedResult.isSet(Account.Name), 'Only Account Name should be set.');
3337-
Assert.isFalse(mockedResult.isSet(Account.Description), 'The Account Description should not be set because it was not included in the SELECT clause.');
3338-
Assert.isFalse(mockedResult.isSet(Account.Website), 'The Account Website should not be set because it was not included in the SELECT clause.');
3337+
Assert.isNull(mockedResult.Description, 'The Account Description should not be set because it was not included in the SELECT clause.');
3338+
Assert.isNull(mockedResult.Website, 'The Account Website should not be set because it was not included in the SELECT clause.');
33393339
}
33403340
}
33413341

33423342
@IsTest
3343-
static void mockWithManyPlainFieldAndSelectNotMockedField() {
3343+
static void mockWithManyPlainFieldsAndSelectNotMockedField() {
33443344
// Setup
33453345
List<Account> accounts = new List<Account>{
33463346
new Account(Name = 'Test 1', Description = 'Test 1 Description', Website = 'www.beyondthecloud.dev'),
@@ -3357,9 +3357,9 @@ private class SOQL_Test {
33573357
for (Account mockedResult : result) {
33583358
Assert.isTrue(mockedResult.isSet(Account.Industry), 'Only Account Industry should be set.');
33593359
Assert.isNull(mockedResult.Industry, 'The Account Industry should be null because it was not specify in mocked records.');
3360-
Assert.isFalse(mockedResult.isSet(Account.Name), 'The Account Name should not be set because it was not included in the SELECT clause.');
3361-
Assert.isFalse(mockedResult.isSet(Account.Description), 'The Account Description should not be set because it was not included in the SELECT clause.');
3362-
Assert.isFalse(mockedResult.isSet(Account.Website), 'The Account Website should not be set because it was not included in the SELECT clause.');
3360+
Assert.isNull(mockedResult.Name, 'The Account Name should not be set because it was not included in the SELECT clause.');
3361+
Assert.isNull(mockedResult.Description, 'The Account Description should not be set because it was not included in the SELECT clause.');
3362+
Assert.isNull(mockedResult.Website, 'The Account Website should not be set because it was not included in the SELECT clause.');
33633363
}
33643364
}
33653365

0 commit comments

Comments
 (0)