Looking at bringing in a selector pattern to help reduce a lot of cumbersome test code. But as I refactored, I noticed that after introducing a selector class, the existing test will fail when it uses System.runAs(). But passes when I comment it out. I would like to understand more about why this is happening.
The class that makes the query is declared as with out sharing and the selector is declared with inherited sharing.
Just to double check I gave every profile in my SB access to the selector class and the base class.
I also updated the selector to run in System.mode()..
public without sharing class AccountSelector extends fflib_SObjectSelector {
public AccountSelector() {
super(false, DataAccess.SYSTEM_MODE);
}
public Schema.SObjectType getSObjectType() {
return Account.SObjectType;
}
}
Here is the method I want to test, it gets one Account and serializes it in a wrapper class for the presentation layer. When tested with System.runAs() it fails to return data.
public static string initializeAccountForm(String accountId) {
AccountSelector accountSelector = (AccountSelector)EMEA_Application.selector.newInstance(Account.SObjectType );
Account accountList = (Account) accountSelector.selectSObjectsById(new Set<Id>{accountId})[0];
return JSON.serialize(
new InitContactFormReturn(
accountList,
PortalAccountController.getCountryCodePicklist(),
PortalAccountController.getPreferredLanguagePicklist()
)
);
}
I don't want to include all the test code because there 100 line of set up to test this method. How could I debug this to figure out what the issue is with System.runAs in this case?
This is the test method with out any mocking. I would like to have a green test before I refactor further with mocks.
@isTest
static void initializeAccountFormTest(){
//Arrange
String serializedResponse;
GcxManageAccountController.InitContactFormReturn parsedResponse;
Account newlyAddedAcct = [
SELECT id, Salutation, FirstName, LastName, DateOfBirth__pc, LanguagePreference__pc, PersonMailingCountry, PersonMailingState,
PersonMailingStreet, PersonMailingCity, PersonMailingPostalCode, PersonEmail, PhoneNumberCountryCode__pc,
Phone, PrimaryPhoneType__pc, SecondaryPhone__pc, SecondaryPhoneType__pc, ShippingCountry, ShippingStreet, ShippingCity, ShippingState, ShippingPostalCode
FROM Account
WHERE PersonEmail = '[email protected]'
LIMIT 1
];
//Act
AccountSelector selector = (AccountSelector)EMEA_Application.selector.newInstance(Account.SObjectType);
System.debug('system mode' + selector.selectSObjectsById(new Set<Id>{newlyAddedAcct.Id})[0]);
Test.startTest();
System.debug('user details are ' + standardTestUser);
System.runAs(standardTestUser){
String result = GcxManageAccountController.initializeAccountForm(newlyAddedAcct.Id);
parsedResponse = (GcxManageAccountController.InitContactFormReturn)JSON.deserialize(result, GcxManageAccountController.InitContactFormReturn.class);
}
Test.stopTest();
system.assertEquals(newlyAddedAcct.PhoneNumberCountryCode__pc, parsedResponse.Account.PhoneNumberCountryCode__pc);
system.assertEquals(PortalAccountController.getCountryCodePicklist().size(), parsedResponse.phoneCountryCodeOptions.size());
}
Below is the query string that the base class is generating.
string representation SELECT id, dateofbirth__pc, firstname, languagepreference__pc, lastname, loqateupdateverification__c, loqateverifiedmailing__pc, loqateverifiedshipping__c, personemail, personmailingcity, personmailingpostalcode, personmailingcountry, personmailingstreet, personmailingstate, phone, phonenumbercountrycode__pc, primaryphonetype__pc, salutation, secondaryphone__pc, secondaryphonetype__pc, shippingcountry, shippingstreet, shippingcity, shippingpostalcode, currencyisocode FROM Account WHERE id in :idSet WITH SYSTEM_MODE ORDER BY CreatedDate ASC NULLS FIRST
And here is all the code from the testSetup method that defines the users
@TestSetup
static void makeData() {
Id runningUserRoleId = [
SELECT Id
FROM UserRole
WHERE DeveloperName = 'Insulet_Super_User_View_All'
LIMIT 1
]?.Id;
Id runningUserProfileId = [
SELECT Id
FROM Profile
WHERE Name = 'Insulet System Administrator'
]
?.Id;
User runningUser = TestDataFactory.createUser(
'Admin',
'User',
'[email protected]',
'en_US',
runningUserRoleId,
runningUserProfileId
);
insert runningUser;
System.runAs(runningUser) {
Id testUserProfileId = [
SELECT Id
FROM Profile
WHERE Name = 'Insulet External Customer'
LIMIT 1
]
?.Id;
insert TestDataFactory.createDataUsePurposes();
Account createdAccount = TestDataFactory.createAccount(
customerAccountRecordTypeId,
'Mr',
'Test',
'User',
Date.today().addDays(-100),
'1234567890',
'1234567890',
'Work',
'Mobile',
testCustomerUserEmail,
'Ireland'
);
Account accountToAdd = TestDataFactory.createAccount(
customerAccountRecordTypeId,
'Mr',
'firstName',
'lastName',
Datetime.now().date().addDays(-100),
'5555555555',
'5555555555',
'Work',
'Mobile',
'[email protected]',
'Ireland'
);
List<Account> acctList = new List<Account>{createdAccount, accountToAdd};
List<Account> acctUpdateList = TestDataFactory.updateAccountsWithPrimaryPhysican(
acctList
, 'ProviderTestolaAccName'
, 'ProviderTestolaContName'
, '[email protected]'
);
insert acctList;
createdAccount = [
SELECT
FirstName,
LastName,
PersonBirthdate,
Phone,
PersonEmail,
PersonContactId
FROM Account
WHERE Id = :createdAccount.Id
];
User customerPortalUser = TestDataFactory.createPersonAccountUser(
createdAccount.FirstName,
createdAccount.LastName,
createdAccount.PersonEmail,
'en_US',
null,
testUserProfileId,
createdAccount.PersonContactId
);
insert customerPortalUser;
}
}
selectSobjectsById
?