Hey I have created a custom apex controller for us to use in cases where we need to lookup IDs from salesforce based on our own IDs coming from our own system. Now I want to test this controller class but I have never expected that it would be so hard to test this.
@RestResource(urlMapping='/accounts/*')
global class CustomAccountController {
@HttpGet
global static void getAccountByCustomerId() {
RestRequest request = RestContext.request;
String customerId = request.requestURI.substring(request.requestURI.lastIndexOf('/')+1);
Account[] accountId = [SELECT id FROM Account WHERE Customer_Id__c = :customerId];
Opportunity[] opportunityId = [SELECT id FROM Opportunity WHERE Customer_Id__c = :customerId];
Lead[] leadId = [SELECT id FROM Lead WHERE Customer_Id__c = :customerId];
SalesforceIds ids = new SalesforceIds();
if (accountId.size() > 0) {
ids.setAccountId(accountId[0].Id);
}
if (opportunityId.size() > 0) {
ids.setOpportunityId(opportunityId[0].Id);
}
if (leadId.size() > 0) {
ids.setLeadId(leadId[0].Id);
}
RestContext.response.responseBody = Blob.valueOf(JSON.serialize(ids));
}
}
then I have my Test class as such:
@isTest
private class CustomAccountControllerTest {
@isTest
static void testReturnIds(){
initData();
Test.startTest();
RestRequest request = new RestRequest();
RestResponse response = new RestResponse();
request.requestURI = '/services/apexrest/accounts/123';
request.httpMethod = 'GET';
RestContext.request = request;
RestContext.response = response;
// Test.createStub(Account, init());
Test.setMock(HttpCalloutMock.class, new MockSalesforceIdsResponse());
CustomAccountController.getAccountByCustomerId();
String res = response.responseBody.toString();
System.assertEquals(getBody(), res);
Test.stopTest();
}
// @IsTest
// static void testNoIdsFound(){
// }
private static String getBody() {
return '{"opportunityId":"0061j00000N0tooAAB","leadId":"00Q1j000007HrxfEAC","accountId":"0011j00001qtE4mAAE"}';
}
static void initData() {
// Accounts
Account account = new Account();
account.Name = 'My Test Account';
account.Customer_Id__c = '123';
insert account;
// Leads
Lead lead = new Lead();
lead.Name = 'My Test Lead';
lead.Customer_Id__c = '123';
insert lead;
// Opportunities
Opportunity opportunity = new Opportunity();
opportunity.Name = 'My Test Opportunity';
opportunity.Customer_Id__c = '123';
insert opportunity;
}
}
Now the current issue is that I get a validation rule not allowing to create new SObjects with the same Customer_Id__c
is it possible to disable that rule in the test? As well another problem is that I am not able to set specific SObject Ids that I want for my testing case just getting the error that the ID field is Not Writable on ex. Account. I have tried all kinds of stuff even tried creating a Lead and trying to Convert that lead just ending up getting a FIELD_INTEGRITY_EXCEPTION
. The Customer_Id__c is possible to exist in all three SObjects but Opportunity just copies it from the associated Account and Account gets it from Lead when Lead is converted. The Test.setMock(...
I can even remove because it does not seem to do anything anyways just something I tried from some of the Apex sources from the documentation. Anyway I am running out of options on how to even write unit tests in Apex for a simple class as the CustomAccountController, and yes name might be misleading in regards that I am fetching something else but that I will fix once I have this test under control.