function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
StenderStender 

Help with writing a Test Class (please).

Hello,

 

I have some functionality that will be prompting a user to export a .csv file (which contains data on Opportunities, Account, and a custom object related to Opps)  that will be consumed by an external ROI tool.  The ROI will then adjust the data and spit it back out in the exact same format.  I then have functionality to allow the user to go to a VF page (from an Opportunity) and then 'upload' the ROI tool.  In actuality what this is doing is updating the data from the .csv into SF.  I have the Controllers and VF pages themselves working just fine, however I am having trouble with the test code.  I have the controllers in two separate classes, but I am hoping to cover them both in a single test class.  Specifically I was hoping to be able to test the Export Controller and then assign the VF page to blob that I can pass in to the Import controller.  But when testing I am getting an error (in the debug log) that says getContent (at the end of the test method below) is not supported in test methods.  Below I will post both Controllers, the Export ROI page (the Import VF page just passes the uploaded file into the controller) and the test class I have so far.  Any and all help would be appreciated!

 

 

Export Controller:

public class ROIExportController {
     
     //this method will return all data needed that is stored on the Opportunity itself.
     public String getOpportunityID(){
        return (ApexPages.currentPage().getParameters().get('id'));
     }
     
     public String getOpportunityName(){
     	Opportunity o = [Select Name FROM Opportunity WHERE Id = :ApexPages.currentPage().getParameters().get('id')];
     	return (o.Name);
     }
     
     public String getOpportunityData(){        
        Opportunity o = [Select Id, Name, RecordTypeId, RecordType.Name, Owner.Name, OwnerId, NoofRooms__c, NoofHotels__c, CurrencyIsoCode, Contract_Term_in_Months__c, Amount, Pricing_Tool_Margin__c From Opportunity o WHERE o.id = :ApexPages.currentPage().getParameters().get('id')]; 
        return (o.Id + ',' + o.Name + ',' +o.Owner.Name + ',' + o.Contract_Term_in_Months__c + ',' + o.NoofHotels__c + ',' + o.NoofRooms__c + ',' + o.CurrencyIsoCode + ',' + o.RecordType.Name + ',' + o.Amount + ',' + o.Pricing_Tool_Margin__c) ;     
     }
     
     public String getAccountData(){
        Account a = [Select a.ShippingStreet, a.ShippingState, a.ShippingPostalCode, a.ShippingCountry, a.ShippingCity, a.Region__c, a.Phone, a.Name, a.Id, a.Account_Market_Segment__c From Account a WHERE a.id = :ApexPages.currentPage().getParameters().get('accountId') ];
        return  (a.Id + ',' + a.Name + ',' + a.ShippingStreet + ',' + a.ShippingCity + ',' + a.ShippingState + ',' + a.ShippingCountry + ',' + a.ShippingPostalCode + ',' + a.Phone + ',' + a.Account_Market_Segment__c + ',' + a.Region__c);
     }
     public String getExchangeRateData(){
        CurrencyType CAD = [Select c.ConversionRate From CurrencyType c WHERE c.IsoCode LIKE 'CAD%' AND c.IsActive = True];
        CurrencyType EUR = [Select c.ConversionRate From CurrencyType c WHERE c.IsoCode LIKE 'EUR%' AND c.IsActive = True];
        CurrencyType GBP = [Select c.ConversionRate From CurrencyType c WHERE c.IsoCode LIKE 'GBP%' AND c.IsActive = True];
        CurrencyType SGD = [Select c.ConversionRate From CurrencyType c WHERE c.IsoCode LIKE 'SGD%' AND c.IsActive = True];
        CurrencyType AUD = [Select c.ConversionRate From CurrencyType c WHERE c.IsoCode LIKE 'AUD%' AND c.IsActive = True];
        return (CAD.ConversionRate + ',' + EUR.ConversionRate + ',' + GBP.ConversionRate + ',' + SGD.ConversionRate + ',' + AUD.ConversionRate);
     }
     public List<Opportunity_Product__c> getOpportunityProductData(){
        List<Opportunity_Product__c> oppProds = [Select Id, Pricing_Record__c, Product_Service__c, Quoted_Recurring_Fee__c, Quoted_Fee_Recurrence__c, Quoted_Multiplier_Fee__c, Quoted_Multiplier_Type_Rec__c, Quoted_Number_of_Transactions__c, Quoted_Number_of_Units_of_Time__c, Quoted_One_Time_Fee__c, Quoted_One_Time_Type__c, Quoted_Time_Based_Fee__c, Quoted_Transaction_Fee__c, Quoted_Transaction_Type__c, Quoted_Unit_of_Time__c, Rack_Recurring_Fee__c, Rack_Fee_Recurrence__c, Rack_Multiplier_Fee__c, Rack_Multiplier_Type_Rec__c, Rack_One_Time_Fee__c, Rack_One_Time_Type__c, Rack_Time_Based_Fee__c, Rack_Transaction_Fee__c, Rack_Transaction_Type__c, Rack_Unit_of_Time__c FROM Opportunity_Product__c WHERE Opportunity_Name__r.Id = :ApexPages.currentPage().getParameters().get('id')];
        return oppProds;
     }
}

 

 

Import Controller (includes a standard from code share Parser):

public class ROIUploadController {

	public Blob contentFile { get; set; }
    public String nameFile { get; set; }
    public Integer rowCount { get; set; }
    public Integer colCount { get; set; } 
    public String errorMessage { get; set; }
    public String successMessage { get; set; }
    
    
    public void updateRecordsWithROICSV(){
    	List<List<String>> attachedCSV = getResults();
    	if(attachedCSV != null){
			//get and update Opportunity Data
			Id oppID = (ApexPages.currentPage().getParameters().get('id'));
			Opportunity Opp = [Select Id From Opportunity WHERE Id = :oppID];
			//assign the appropriate row of data as the Opporutniy data row
			List<String> oppDataRow = attachedCSV.get(2);
			//Had to use trim() method below to get rid of a leading space in the Opp's ID.  I will use this in the rest of this code for ALL IDs listed in the .csv
			ID csvOppID = oppDataRow.get(0).trim(); 			
			//If the ID in the .csv = the ID of the Opp selected in SF are, then update the Opp's Amount and Margin from the relevant fields in the uploaded .csv
			If( csvOppID == oppID){
				//update the Opp fields IN MEMORY ONLY.  The real update to the record takes place below where all Opp Prod records will also be updated.
				Opp.amount = decimal.ValueOf(oppDataRow.get(8));
				Opp.Pricing_Tool_Margin__c = decimal.ValueOf(oppDataRow.get(9));
				//make sure there is an entry on the first Opp Prod row, if so there is at least one Opp Prod in the .csv
				If(attachedCSV.get(11) != null){
					//get a full list of Opp Prods in SF and a list of those in the CSV, compare them before making any updates.					
					List<Opportunity_Product__c> oppProdsInSF = [Select ID, Pricing_Record__c, Product_Service__c from Opportunity_Product__c WHERE Opportunity_Name__c = :oppID];
					Set<ID> oppProdIDsinSF = new Set<ID>();
					Set<ID> oppProdIDsinCSV = new Set<ID>();
					For(Opportunity_Product__c oP :oppProdsInSF){
						oppProdIDsinSF.add(oP.ID);
					}
					//set up a while loop that adds all IDs for Opp Prods in the .csv to a set of IDs(to be compared to the list in SF), meanwhile create a list of lists for all of the Opp Product rows in the csv
					Integer i = 11;
					List<List<String>> allOppProdRows = new List<List<String>>();
					List<String> currentOppProdCSV = new List<String>();
					While( i < attachedCSV.size() ){
						currentOppProdCSV = attachedCSV[i];
						allOppProdRows.add(attachedCSV[i]);
						ID currentOPID = currentOppProdCSV[0].trim();
						oppProdIDsinCSV.add(currentOPID);
						i++;
					}
					//compare the two Sets of IDs and if they are = continue, else give error saying they do not match.
					If(oppProdIDsinSF == oppProdIDsinCSV){
						boolean isError = false;
						For(Opportunity_Product__c currentSFOppProd :oppProdsInSF){
							IF (isError == false){
								For(List<String> currentOppProdRow :allOppProdRows){
									//check to see if IDs match, if so follow that to make sure P/S and pricing record IDs match.  If those match, make the updates.
									If(currentOppProdRow[0].trim() == currentSFOppProd.Id){
										If(currentOppProdRow[1].trim() == currentSFOppProd.Pricing_Record__c && currentOppProdRow[2].trim() == currentSFOppProd.Product_Service__c){
											currentSFOppProd.Quoted_Recurring_Fee__c = decimal.ValueOf(currentOppProdRow[3]);
											currentSFOppProd.Quoted_Fee_Recurrence__c = currentOppProdRow[4];
											currentSFOppProd.Quoted_Multiplier_Fee__c = decimal.ValueOf(currentOppProdRow[5]);
											currentSFOppProd.Quoted_Multiplier_Type_Rec__c = currentOppProdRow[6];
											currentSFOppProd.Quoted_Number_of_Transactions__c = decimal.ValueOf(currentOppProdRow[7]);
											currentSFOppProd.Quoted_Number_of_Units_of_Time__c = decimal.ValueOf(currentOppProdRow[8]);
											currentSFOppProd.Quoted_One_Time_Fee__c = decimal.ValueOf(currentOppProdRow[9]);
											currentSFOppProd.Quoted_One_Time_Type__c = currentOppProdRow[10];
											currentSFOppProd.Quoted_Time_Based_Fee__c = decimal.ValueOf(currentOppProdRow[11]);
											currentSFOppProd.Quoted_Transaction_Fee__c = decimal.ValueOf(currentOppProdRow[12]);																	
											currentSFOppProd.Quoted_Transaction_Type__c = currentOppProdRow[13];
											currentSFOppProd.Quoted_Unit_of_Time__c = currentOppProdRow[14];											
										} else {
											//set isError = true and break the loop, the error will be thrown by the parent Else in the parent IF(), which will also break the parent FOR()
											isError = true;
											break;																					}
									}							
								}	
							} else {
								//errorMessage = 'The selected Product/Service records in SF do not match those in the uploaded .csv.  If you have made any changes to the Product/Services and/or Pricing records listed for this Opportunity, you MUST export a new .csv for the ROI, re-enter the quoted prices there and upload the new .csv file it creates.';
								ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'The selected Product/Service records in SF do not match those in the uploaded .csv.  If you have made any changes to the Product/Services and/or Pricing records listed for this Opportunity, you MUST export a new .csv for the ROI, re-enter the quoted prices there and upload the new .csv file it creates.'));								
								break;								
							}														
						}		
						If(isError == false){
							//at this point all updates can be made:					
							database.update(Opp);
							database.update(oppProdsInSF);
							//errorMessage = '';
							//successMessage = 'File successfully uploaded and Opportunity updated.  Please close this window and refresh the Opportunity page.';
							ApexPages.addmessage(new ApexPages.message(ApexPages.severity.CONFIRM, 'File successfully uploaded and Opportunity updated.  Please close this window and refresh the Opportunity page.'));
						}						
					} else {
						//throw Error for when list of Opp Prod IDs do not match.
						//errorMessage = 'The list of Opportunity Products in the uploaded .csv does not match the list for this Opportunity in SF.  If you added or removed an Opportunity Product for this Opportunity, you MUST export a new .csv for the ROI, re-enter the quoted prices there and upload the new .csv file it creates.';
						ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'The list of Opportunity Products in the uploaded .csv does not match the list for this Opportunity in SF.  If you added or removed an Opportunity Product for this Opportunity, you MUST export a new .csv for the ROI, re-enter the quoted prices there and upload the new .csv file it creates.'));
					}					 
				}													
			} else{
				//errorMessage = 'The Opportunity in the selected .csv does not match the selected Opportunity in SF.  Please make sure you are selecting the correct Opportunity and .csv file when uploading.  If you still receive this error you may need to start over with a fresh export from SF.  Please contact SHS SF Support at SHSSalesForceSupport@sabre.com if you have any questions or concerns.';
				ApexPages.addmessage(new ApexPages.message(ApexPages.severity.ERROR,'The Opportunity in the selected .csv does not match the selected Opportunity in SF.  Please make sure you are selecting the correct Opportunity and .csv file when uploading.  If you still receive this error you may need to start over with a fresh export from SF.  Please contact SHS SF Support at SHSSalesForceSupport@sabre.com if you have any questions or concerns.'));								
			}									    		
    	}
    }
    
    /* begin standard Parser code.  getResults returns the parsedCSV in a List<List<String>> */

 

 

Export VF Page:

<apex:page controller="ROIExportController" contentType="application/csv#{!OpportunityName}.csv" cache="true" showheader="false">
<apex:outputText value="Opportunity Data"/>
    ID,Name,Analyst Name,Contract Length,Number of Properties,Rooms,Currency, Record Type Name, Amount, Pricing Tool Margin
   {!OpportunityData}
    Account Data
    Account ID,Account Name,Shipping Street,Shipping City,Shipping State,Shipping Country,Shipping Zip,Phone Number,Customer Type,Region
    {!AccountData}
    Exchange Rates
    CAD,EUR,GBP,SGD,AUD
    {!ExchangeRateData}
    Products
    Opportunity Product ID,Pricing Record ID,Product/Service ID,Quoted: Recurring Fee,Quoted: Fee Recurrence,Quoted: Multiplier Fee,Quoted: Multiplier Type/Rec,Quoted: Number of Transactions,Quoted: Number of Units of Time,Quoted: One-Time Fee,Quoted: One-Time Type Fee,Quoted: Time-Based Fee,Quoted: Transaction Fee,Quoted: Transaction Type,Quoted: Unit of Time,Rack: Recurring Fee,Rack: Fee Recurrence,Rack: Multiplier Fee,Rack: Multiplier Type/Rec,Rack: One-Time Fee,Rack: One-Time Type,Rack: Time Based Fee,Rack: Transaction Fee,Rack: Transaction Type,Rack: Unit of Time
    <apex:repeat value="{!OpportunityProductData}" var="currentOppProd">
        {!currentOppProd.Id},{!currentOppProd.Pricing_Record__c},{!currentOppProd.Product_Service__c},{!currentOppProd.Quoted_Recurring_Fee__c},{!currentOppProd.Quoted_Fee_Recurrence__c},{!currentOppProd.Quoted_Multiplier_Fee__c},{!currentOppProd.Quoted_Multiplier_Type_Rec__c},{!currentOppProd.Quoted_Number_of_Transactions__c},{!currentOppProd.Quoted_Number_of_Units_of_Time__c},{!currentOppProd.Quoted_One_Time_Fee__c},{!currentOppProd.Quoted_One_Time_Type__c},{!currentOppProd.Quoted_Time_Based_Fee__c},{!currentOppProd.Quoted_Transaction_Fee__c},{!currentOppProd.Quoted_Transaction_Type__c},{!currentOppProd.Quoted_Unit_of_Time__c},{!currentOppProd.Rack_Recurring_Fee__c},{!currentOppProd.Rack_Fee_Recurrence__c},{!currentOppProd.Rack_Multiplier_Fee__c},{!currentOppProd.Rack_Multiplier_Type_Rec__c},{!currentOppProd.Rack_One_Time_Fee__c},{!currentOppProd.Rack_One_Time_Type__c},{!currentOppProd.Rack_Time_Based_Fee__c},{!currentOppProd.Rack_Transaction_Fee__c},{!currentOppProd.Rack_Transaction_Type__c},{!currentOppProd.Rack_Unit_of_Time__c}
    </apex:repeat>
</apex:page>

 

finally the Test Code so far:

@isTest
private class TESTROIExportAndImportController {

    static testMethod void myUnitTest() {
    	User u = [Select LastName, Id, FirstName, Email From User WHERE IsActive = True AND UserType = 'Standard' AND UserRole.Name LIKE '%Admin%' LIMIT 1];
    	Account a = new Account(Name = 'Test Account', OwnerID = u.id);
        insert a;
        Contact c = new Contact(AccountID = a.id, OwnerID = u.Id, FirstName = u.FirstName, LastName = u.LastName, Email = u.Email);
    	insert c;
        Opportunity o = new Opportunity(Name = 'Test Opp', AccountID = a.Id, StageName = 'Qualified', CloseDate = date.Today(), OwnerID = u.id);
        insert o;
        Opportunity_Product__c oP = new Opportunity_Product__c (Opportunity_Name__c = o.id);
        insert oP;
        
        //set current page to that of the ROIExport page.
        PageReference pg = Page.ROIExport;
        pg.getParameters().put('id', o.Id);
        pg.getParameters().put('accountId', a.Id);
        Test.setCurrentPage(pg);
        
        //Add parameters to page URL
        ApexPages.currentPage().getParameters().put('id', o.Id);
        ApexPages.currentPage().getParameters().put('accountId', a.Id);
        
        
        
        //instantiate the Controller and then assign all methods in the ROIExportController class to variables
        ROIExportController exportController = new ROIExportController();
        String OppID = exportController.getOpportunityID();
        String OppName = exportController.getOpportunityName();
        String OppData = exportController.getOpportunityData();
        String AccountData = exportController.getAccountData();
        String ExchangeData = exportController.getExchangeRateData();
        List<Opportunity_Product__c> OppProds = exportController.getOpportunityProductData();
        
        
        
        Blob csvFile = pg.getContent();// Apexpages.currentPage().getContent() does not work either.
        System.debug(csvFile);
        
        
    }
}

 

 

 

Thanks in advance for any and all help!

Jeremy Stender

Daniel.ReidDaniel.Reid

Hello Stebder,

 

There are some functions that cannot be run from within a testmethod. PageRegeference.getContent() is one of them, as listed in the documentation for PageReference methods. 

 

Often you can disable calls for those functions using System.test.isRunningTest(), and then create data locally (within the function or testMethod) to test against.  In your case, I would recommend creating a sample Blob within the testmethod itself.

 

Let me know if you would like to discuss this more, or need additional help.

 

Daniel Reid
Contact us - We can help!

Salesforce Superheroes
------------------------------
help@salesforcesuperheroes.com
www.salesforcesuperheroes.com
1-888-407-9578 x102