I created a VisualForce page to process CSV files for people to create leads. For some reason when I go to call the method for my test class to read the CSV file I am getting the error Non static method cannot be referenced from a static context: void UploadCSVController.ReadFromFile()
. Is there certain ways you need to do this for a test class?
VP Page:
<apex:page lightningStylesheets="true" controller="UploadCSVController">
<h1 style="font-size:30px"><center>Automation Upload</center></h1><br/><br/>
<apex:form id="idForm">
<apex:pageMessages /><br/><br/>
<apex:pageBlock tabStyle="Lead" id="idInputBlock">
<p style="height:13px; font-size:13px"><b>Set the first column of the CSV file as LastName Field:</b></p><br/>
<apex:inputFile value="{!fileBody}" fileSize="{!fileSize}" fileName="{!fileName}" accept=".csv" contentType="text/csv" id="idInputFile"></apex:inputFile>
<!-- Input File -->
<apex:commandButton value="Upload File" action="{!ReadFromFile}" onclick="document.getElementById('actionStatusUP').style.display = 'inline';" />
<!-- Upload Button to upload file -->
<img src="/img/loading.gif" style="display:none" id="actionStatusUP" />
<apex:pageBlockButtons location="bottom" >
<!-- Save Button to insert the records -->
<apex:commandButton value="Save" action="{!save}" rendered="{! reVariableSave}" onclick="document.getElementById('imageSV').style.display = 'inline';" />
<img src="/img/loading.gif" style="display:none" id="imageSV" />
</apex:pageBlockButtons>
<p style="height:13px; font-size:13px"><b><br/>
Please be sure to upload a .csv file. You can find an example for the file type
<apex:commandLink action="https://storecapital--sandboxa--c.sandbox.vf.force.com/resource/1669504995000/PitchbookTestFile?" value="here"/></b>
</p>
<br/>
</apex:pageBlock>
<apex:pageBlock rendered="{! reVariableBlock}" id="idTable">
<apex:pageBlockSection collapsible="false" columns="2" >
<p><b>Total Records in CSV File: </b></p>
<apex:outputText value="{! totalRecords}" style="color:black" />
<p><b>Number of Records Successfully inserted: </b></p>
<apex:outputText value="{! insertedRecords}" style="color:green" />
<p><b>Number of Failed Records: </b></p>
<apex:outputText value="{! failedRecords}" style="color:red" />
</apex:pageBlockSection><br/>
<center><p style="color:dodgerblue;font-size:25px"><b>Details of the inserted records</b></p></center><br/><br/>
<apex:pageBlockTable value="{! leadsList}" rendered="{! reVariable}" var="lds" >
<!-- Table to display details of inserted records -->
<apex:repeat value="{! fieldNamesList}" var="fld" >
<apex:column value="{! lds[fld]}" />
</apex:repeat>
</apex:pageBlockTable>
</apex:pageBlock>
</apex:form>
</apex:page>
Controller:
public with sharing class UploadCSVController {
//Public Variables----------------------------------------------------------------------------------------------------------------------------------------------
public transient Blob fileBody{ get; set; } //fileBody
public transient Integer fileSize{ get; set; } //fileSize
public transient String fileName{ get; set; } //fileName
public List<Lead> leadsList{ get; set; } //List of inserted Leads
public List<String> fieldNamesList{ get; set; } //List of fields in Lead Object's fields which are avaiable in CSV
public Boolean reVariableSave{ get; set; } //Variable to render Save Button
public Boolean reVariableBlock{ get; set; } //Variable to render PageBlock with inserted record details
public Boolean reVariable{ get; set; } //Variable to render Record Details Table
public Integer totalRecords{ get; set; } //Total number of records in CSV File
public Integer insertedRecords{ get; set; } //Number of records successfully inserted
public Integer failedRecords{ get; set; } //Number of failed records
//Private Variables----------------------------------------------------------------------------------------------------------------------------------------------
String fileBodyAsString = '';
//String value of file Body
String header = '';
//Constructor----------------------------------------------------------------------------------------------------------------------------------------------------
public UploadCSVController(){
leadsList = new List<SObject>();
fieldNamesList = new List<String>();
reVariableSave = false;
reVariableBlock = false;
reVariable = false;
totalRecords = 0;
insertedRecords = 0;
failedRecords = 0;
}
//Method to check file size and whether the file body is readable------------------------------------------------------------------------------------------------
public void ReadFromFile(){
reVariableBlock = false;
if(fileSize < 3280760 && fileName.substringAfterLast('.').equalsIgnoreCase('csv')){
system.debug('file size' + filesize);
system.debug('file name after' + fileName.substringAfterLast('.'));
system.debug('fileBodyAsString ' + fileBodyAsString);
system.debug('fileBody.toString() ' + fileBody.toString());
try{
fileBodyAsString = fileBody.toString();
ReadCSVFile();
}
catch(exception e){
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'Error reading CSV file'));
}
}
else{
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'No File Chosen or,'));
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'File Size greater than 50 KB or,'));
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR,'File is not of CSV type'));
}
}
//Method to read the file and create a Lead list which will be inserted and check exceptions in CSV file------------------------------------------------------
private void ReadCSVFile(){
if(fileBodyAsString.length() > 100000){
header = fileBodyAsString.substring(0, 2000).split('\n')[0];
system.debug('line 67 passed');
}
else{
header = fileBodyAsString.split('\n')[0];
system.debug('line 71 passed');
}
fileBodyAsString = fileBodyAsString.substringAfter('\n');
system.debug('field Name List before clear ' + fieldNamesList);
leadsList.clear();
fieldNamesList.clear();
system.debug('line 78 passed');
for(String str : header.split('\n')[0].split(',')){
fieldNamesList.add(str.trim());
}
system.debug('line 81 passed');
system.debug('fieldNamesList line 81 ' + fieldNamesList);
String LeadDetails = '';
Map<string, SObjectField> fieldNamesMap = Schema.getGlobalDescribe().get('Lead').getDescribe().fields.getMap();
System.debug('Field Name List After Clear before if check ' + fieldNamesList);
System.debug('Field Name List After Clear before if check ' + fieldNamesList[0]);
system.debug('line 84 passed');
System.debug('fieldNamesMap ' + fieldNamesMap);
System.debug('LeadDetails ' + LeadDetails);
if(fieldNamesList[0].equalsIgnoreCase('LastName')){
System.debug('Line 91 passed');
Lead lds = new Lead();
Integer flag = 0;
while( !String.isEmpty(fileBodyAsString)){
//Itereation over each Lead
if(fileBodyAsString.length() > 100000){
leadDetails = fileBodyAsString.substring(0, 100000).split('\n')[0];
}
else{
leadDetails = fileBodyAsString.split('\n')[0];
}
fileBodyAsString = fileBodyAsString.substringAfter('\n');
String lastnameValue = leadDetails.substringBefore(',').trim();
for(Integer j=0; j<fieldNamesList.size(); j++){
//Iterating over the fields & assigning value to them for each Lead
Schema.DisplayType fieldType = fieldNamesMap.get(fieldNamesList[j]).getDescribe().getType();
if( fieldType == Schema.DisplayType.DATE ){
//Setting value of fields which are of Date Type
try{
lds.put(fieldNamesList[j].trim(), Date.valueOf(leadDetails.substringBefore(',').trim()));
}
catch(Exception e){
flag = 1;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Empty '
+ fieldNamesList[j].trim()
+ ' field or Date is not in format \"YYYY-MM-DD\" for record with LastName = '
+ lastnameValue));
}
}
else if( fieldType == Schema.DisplayType.DATETIME ){ //Setting value of fields which are of DateTime Type
try{
lds.put(fieldNamesList[j].trim(), Datetime.valueOf(leadDetails.substringBefore(',').trim()));
}
catch(Exception e){
flag = 1;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Empty ' + fieldNamesList[j].trim()
+ ' field or DateTime is not in format \"YYYY-MM-DD HH:MM:SS\" for record with LastName = '
+ lastnameValue));
}
}
else if( fieldType == Schema.DisplayType.BOOLEAN ){ //Setting value of fields which are of Boolean Type
if(leadDetails.substringBefore(',').trim().equalsIgnoreCase('true')
|| leadDetails.substringBefore(',').trim().equalsIgnoreCase('false')
|| leadDetails.substringBefore(',').trim() == ''){
lds.put(fieldNamesList[j].trim(), Boolean.valueOf(leadDetails.substringBefore(',').trim()));
}
else{
flag = 1;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Acceptable value for '
+ fieldNamesList[j].trim()
+ ' field is \"TRUE/FALSE\" for record with LastName = '
+ lastnameValue));
}
}
else if( fieldType == Schema.DisplayType.TEXTAREA ){ //Setting value of fields which are of TextArea Type
if(leadDetails.left(1) != '\"'){
//Setting value of fields which are of TextArea Type with comma
lds.put(fieldNamesList[j].trim(), leadDetails.substringBefore(',').trim());
}
else{
//Setting value of fields which are of TextArea Type without comma
lds.put(fieldNamesList[j].trim(), leadDetails.substringBetween('\"', '\"') .trim());
leadDetails = leadDetails.substringAfter('\"').substringAfter('\"');
}
}
else{
//Setting value of all other type of fields
try{
lds.put(fieldNamesList[j].trim(), leadDetails.substringBefore(',').trim());
}
catch(Exception e){
flag = 1;
}
}
leadDetails = leadDetails.substringAfter(',');
}
leadsList.add(lds);
lds = new Lead();
}
if(flag != 1){
//If there is no exception, show Save button
reVariableSave = true;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Click Save Button to insert the Records '));
}
}
else{
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'This has failed to work .... shit'));
}
}
//Save method to insert the Lead Recods and counting inserted records and failed records----------------------------------------------------------------------
public Pagereference save(){
reVariableBlock = true;
Database.SaveResult[] srList = Database.insert(leadsList, false);
leadsList.clear();
Set<Id> savedLeadIdSet = new Set<Id>();
totalRecords = 0;
insertedRecords = 0;
failedRecords = 0;
for (Database.SaveResult sr : srList) {
++totalRecords;
if (!sr.isSuccess()) {
++failedRecords;
for(Database.Error err : sr.getErrors()) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, err.getStatusCode()
+ ': ' + err.getMessage()
+ ' for Record at Line Number: '
+ (totalRecords + 1)));
}
}
else{
++insertedRecords;
savedLeadIdSet.add(sr.getId());
}
}
leadsList = Database.query('SELECT ' + header + ' FROM Lead WHERE Id in :savedLeadIdSet');
if(leadsList.size() > 0 && leadsList.size()<400){
reVariable = true;
}
return null;
}
}
Test Class:
@isTest
public class TestUploadCSVController {
static testmethod void testfileupload(){
String body = 'LastName,firstName,Title,Company\n Testerson, Test, CEO, Rule27\n Testing, Tester, CIO, Rule27';
String OUTPUT_DOCUMENT_NAME = 'Test File';
insert new ContentVersion(
Title = OUTPUT_DOCUMENT_NAME,
PathOnClient = OUTPUT_DOCUMENT_NAME + '.csv',
VersionData = Blob.valueOf(body),
ContentLocation = 'S'
);
UploadCSVController.ReadFromFile();
}
static testmethod void testfileuploadNegative(){
}
}
====================================================== After help I was able to get this solved:
Test Class:
@isTest
public class TestUploadCSVController {
static testmethod void testfileupload1(){
String OUTPUT_DOCUMENT_NAME = 'Test File.csv';
String body = 'LastName,FirstName,Company,Title,LeadSource,Email, STORE_Verified__c, Targeted__c, Description\n '+
'me,Test,Test Company ,CEO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'you,Test,Test Company ,CIO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'Us,Test,Test Company ,CTO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester5,Test,Test Company ,CXO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester1,Test,Test Company ,COO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester2,Test,Test Company ,CSO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester3,Test,Test Company ,"Vp, Technology",Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester4,Test,Test Company ,"VP, Clicent Success",Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.';
Blob fileBody = Blob.valueOf(body);
//set current page to vf
PageReference PageReference = Page.UploadCSVControllerPage;
test.setCurrentPage(PageReference);
//pass in id from blob to idInputFile
UploadCSVController controllerInstance = new UploadCSVController();
// Then call the instance method
controllerInstance.fileBody = filebody;
controllerInstance.fileSize = 502;
controllerInstance.fileName = OUTPUT_DOCUMENT_NAME;
controllerInstance.ReadFromFile();
controllerInstance.save();
}
static testmethod void testfileupload2(){
String OUTPUT_DOCUMENT_NAME = 'Test File.xls';
String body = 'LastName,FirstName,Company,Title,LeadSource,Email, STORE_Verified__c, Targeted__c, Description\n '+
'me,Test,Test Company ,CEO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'you,Test,Test Company ,CIO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'Us,Test,Test Company ,CTO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester5,Test,Test Company ,CXO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester1,Test,Test Company ,COO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester2,Test,Test Company ,CSO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester3,Test,Test Company ,"Vp, Technology",Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester4,Test,Test Company ,"VP, Clicent Success",Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.';
Blob fileBody = Blob.valueOf(body);
//set current page to vf
PageReference PageReference = Page.UploadCSVControllerPage;
test.setCurrentPage(PageReference);
//pass in id from blob to idInputFile
UploadCSVController controllerInstance = new UploadCSVController();
// Then call the instance method
controllerInstance.fileBody = filebody;
controllerInstance.fileSize = 502;
controllerInstance.fileName = OUTPUT_DOCUMENT_NAME;
controllerInstance.ReadFromFile();
}
static testmethod void testfileupload3(){
String OUTPUT_DOCUMENT_NAME = 'Test File.csv';
String body = 'LastName,FirstName,Company,Title,LeadSource,Email, STORE_Verified__c, Targeted__c, Description\n '+
'me,Test,Test Company ,CEO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'you,Test,Test Company ,CIO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'Us,Test,Test Company ,CTO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester5,Test,Test Company ,CXO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester1,Test,Test Company ,COO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester2,Test,Test Company ,CSO,Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester3,Test,Test Company ,"Vp, Technology",Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.\n' +
'tester4,Test,Test Company ,"VP, Clicent Success",Other,[email protected],TRUE, 12/01/2022, This is a long text description. Please take a look and then tell us if this has passed.';
Blob fileBody = Blob.valueOf(body);
//set current page to vf
PageReference PageReference = Page.UploadCSVControllerPage;
test.setCurrentPage(PageReference);
//pass in id from blob to idInputFile
UploadCSVController controllerInstance = new UploadCSVController();
// Then call the instance method
controllerInstance.fileBody = filebody;
controllerInstance.fileSize = 502;
controllerInstance.fileName = OUTPUT_DOCUMENT_NAME;
controllerInstance.ReadFromFile();
controllerInstance.save();
}
}
testmethod
keyword is deprecated, and you should be using the@isTest
annotation instead. Yes, it gets used for both the top level class as well as the methods that execute the actual tests.