I have the LightningSelfRegisterController and LightningSelfRegisterControllerTest that were prebuilt in SF. The test only covers the class at something like 72%. I need to get this to 90% and am focusing on the following code that isn't covered:
CLASS
global class LightningSelfRegisterController {
< ... bunch of code that works and is covered ...>
@AuraEnabled
public static List<Map<String,Object>> getExtraFields(String extraFieldsFieldSet) {
List<Map<String,Object>> extraFields = new List<Map<String,Object>>();
Schema.FieldSet fieldSet = Schema.SObjectType.User.fieldSets.getMap().get(extraFieldsFieldSet);
system.debug('extraFieldsFieldSet is '+extraFieldsFieldSet);
system.debug('fieldSet is ' +fieldSet);
//if(!Test.isRunningTest()) { Removed not running test so we can cover the following lines
if (fieldSet != null) {
for (Schema.FieldSetMember f : fieldSet.getFields()) {
Map<String, Object> fieldDetail = new Map<String, Object>();
fieldDetail.put('dbRequired', f.getDBRequired());
fieldDetail.put('fieldPath', f.getFieldPath());
fieldDetail.put('label', f.getLabel());
fieldDetail.put('required', f.getRequired());
fieldDetail.put('type', f.getType());
fieldDetail.put('value', ''); // client will populate
extraFields.add(fieldDetail);
}}//} - Removed not running test above
return extraFields;
}
}
TEST CLASS
@IsTest
public without sharing class LightningSelfRegisterControllerTest {
< ... bunch of code that works and covers the class ...>
@IsTest
static void testGetExtraExtraFields() {
MetadataService.MetadataPort service = createService();
// FieldSet
MetadataService.FieldSet fieldSet = new MetadataService.FieldSet();
fieldSet.fullName = 'Test__c.MyFieldSet';
fieldSet.label = 'My FieldSet';
fieldSet.description = 'Used by my VF page';
MetadataService.FieldSetItem myAvailableField = new MetadataService.FieldSetItem();
myAvailableField.field = 'TestField__c';
myAvailableField.isFieldManaged = true;
myAvailableField.isRequired = true;
fieldSet.availableFields = new List<MetadataService.FieldSetItem>();
fieldSet.availableFields.add(myAvailableField);
// Create
MetadataService.AsyncResult[] results = service.create(new List<MetadataService.Metadata> { fieldSet });
/*List < Map < String, Object >> fieldlist = new List < Map < String, Object >> ();
Map < String, String > paramsMap = initializeParams();
Map < String, Object > fieldMap = new Map < String, Object > ();
fieldMap.put('description', 'new field');
fieldMap.put('fieldPath', 'dummyPath');
fieldlist.add(fieldMap);*/
String extraFields = fieldset.fullName;
//String extraFields = JSON.serialize(fieldset);
System.assertEquals(new List < Map < String, Object >> (), LightningSelfRegisterController.getExtraFields(extraFields));
}
}
I tried implementing the method of creating the fieldset using the MetadaService class based on Can we insert or update FieldSets using apex code?. I had to add some bits of the MetadataService class that were not present in our version -- grabbed from https://github.com/financialforcedev/apex-mdapi/blob/master/apex-mdapi/src/classes/MetadataServiceExamples.cls#L492.
I know it would be better to use the fieldset from the VF Page or component using this class, but we are not currently using this code and need it for future use.
Currently the code above runs without error. The problem is that it doesn't wind up covering that code section. When I system.debug the value in the class for "extraFieldsFieldSet" I get "Test__c.MyFieldSet". But when I system.debug the value for "fieldSet" I get null.
What exactly is
Schema.SObjectType.User.fieldSets.getMap().get();
actually looking for? If it is the fieldSet.FullName value, that is what I am passing. But is that the right thing?
EDIT
Now my test code has incorporated more of the MetadataService which got it to work to the level of getting a new error message saying that the TestMethod cannot make a Web Callout. So I inserted a mock web service. Which worked in getting rid of that error message, but now I have a new error message "attempt to dereference a null object." from the line:
handleSaveResults(results[0]);
So it looks like the attempt to create the metadata fieldset in the line above is producing no results. Here is what my code now looks like for the test class:
@IsTest
static void testGetExtraExtraFields() {
System.Test.setMock(WebServiceMock.class, new WebServiceMockImpl());
Test.startTest();
MetadataService.MetadataPort service = createService();
// FieldSet
MetadataService.FieldSet fieldSet = new MetadataService.FieldSet();
fieldSet.fullName = 'Test__c.MyFieldSet';
fieldSet.label = 'My FieldSet';
fieldSet.description = 'Used by my VF page';
MetadataService.FieldSetItem myAvailableField = new MetadataService.FieldSetItem();
myAvailableField.field = 'TestField__c';
myAvailableField.isFieldManaged = true;
myAvailableField.isRequired = true;
fieldSet.availableFields = new List<MetadataService.FieldSetItem>();
fieldSet.availableFields.add(myAvailableField);
// Create
List<MetadataService.SaveResult> results =
service.createMetadata(
new MetadataService.Metadata[] { fieldSet });
handleSaveResults(results[0]);
System.assertEquals(new List < Map < String, Object >> (), LightningSelfRegisterController.getExtraFields(fieldset.fullName));
Test.stopTest();
}
private class WebServiceMockImpl implements WebServiceMock
{
public void doInvoke(
Object stub, Object request, Map<String, Object> response,
String endpoint, String soapAction, String requestName,
String responseNS, String responseName, String responseType)
{
if(request instanceof MetadataService.retrieve_element)
response.put('response_x', new MetadataService.retrieveResponse_element());
else if(request instanceof MetadataService.checkDeployStatus_element)
response.put('response_x', new MetadataService.checkDeployStatusResponse_element());
else if(request instanceof MetadataService.listMetadata_element)
response.put('response_x', new MetadataService.listMetadataResponse_element());
else if(request instanceof MetadataService.checkRetrieveStatus_element)
response.put('response_x', new MetadataService.checkRetrieveStatusResponse_element());
else if(request instanceof MetadataService.describeMetadata_element)
response.put('response_x', new MetadataService.describeMetadataResponse_element());
else if(request instanceof MetadataService.deploy_element)
response.put('response_x', new MetadataService.deployResponse_element());
else if(request instanceof MetadataService.updateMetadata_element)
response.put('response_x', new MetadataService.updateMetadataResponse_element());
else if(request instanceof MetadataService.renameMetadata_element)
response.put('response_x', new MetadataService.renameMetadataResponse_element());
else if(request instanceof MetadataService.cancelDeploy_element)
response.put('response_x', new MetadataService.cancelDeployResponse_element());
else if(request instanceof MetadataService.deleteMetadata_element)
response.put('response_x', new MetadataService.deleteMetadataResponse_element());
else if(request instanceof MetadataService.upsertMetadata_element)
response.put('response_x', new MetadataService.upsertMetadataResponse_element());
else if(request instanceof MetadataService.createMetadata_element)
response.put('response_x', new MetadataService.createMetadataResponse_element());
else if(request instanceof MetadataService.deployRecentValidation_element)
response.put('response_x', new MetadataService.deployRecentValidationResponse_element());
else if(request instanceof MetadataService.describeValueType_element)
response.put('response_x', new MetadataService.describeValueTypeResponse_element());
else if(request instanceof MetadataService.checkRetrieveStatus_element)
response.put('response_x', new MetadataService.checkRetrieveStatusResponse_element());
return;
}
}
public static void handleSaveResults(MetadataService.SaveResult saveResult)
{
// Nothing to see?
if(saveResult==null || saveResult.success)
return;
// Construct error message and throw an exception
if(saveResult.errors!=null)
{
List<String> messages = new List<String>();
messages.add(
(saveResult.errors.size()==1 ? 'Error ' : 'Errors ') +
'occured processing component ' + saveResult.fullName + '.');
for(MetadataService.Error error : saveResult.errors)
messages.add(
error.message + ' (' + error.statusCode + ').' +
( error.fields!=null && error.fields.size()>0 ?
' Fields ' + String.join(error.fields, ',') + '.' : '' ) );
if(messages.size()>0)
throw new MetadataServiceExamplesException(String.join(messages, ' '));
}
if(!saveResult.success)
throw new MetadataServiceExamplesException('Request failed with no specified error.');
}
public class MetadataServiceExamplesException extends Exception { }
}