How to create unit test for Apex Controller that responds to user input?












1














I have a process that has been built that presents a visualforce page to the user, they first select a price book, and a section on page is refreshed. They are presented with a list of products from that price book. Once they select a product, a record is created on the Quoted_Products__c custom object. This process works fine and my problem is I have no idea how to write a unit test for simulating user selections on the visualforce page.



I have no test code to show as I have no idea where start. Doing some Google Fu I am only finding how to create test users and to run a test as a user and the like. I am not seeing anything on how to simulate a user making selections. Do I just make some assumptions on user selection and then run the very last process that creates the records? If so, how to set the required variables into the test page environment?



Below is my Controller and the Visualforce page. Any pointers would be great.



Visualforce Page



<apex:page Controller="queryProduct"> 

<apex:pageBlock >
<apex:pageBlockSection title="Active Quote Detail">
<apex:pageBlockTable value="{! quotedetails }" var="qd">
<apex:column value="{! qd.Id }"/>
<apex:column value="{! qd.Name }"/>
<apex:column value="{! qd.Account__r.Name }"/>
<apex:column value="{! qd.CurrencyIsocode }"/>
</apex:pageBlockTable>
</apex:pageBlockSection>

<apex:pageBlockSection title="Pricebook selection">
<apex:form >
<apex:outputLabel value="Which Pricebook? :"/>
<apex:selectList value="{! selected_Pricebook}" size="1">
<apex:selectOptions value="{! pricebook_name}"/>
</apex:selectList>
<br /><br />
<apex:commandButton value="Show Products" action="{!search}" rerender="out"/>
<apex:commandButton value="Clear" action="{!clear}"/>
</apex:form>
</apex:pageBlockSection>

<apex:outputPanel id="out">
<apex:pageBlock title="Selected PriceBook" rendered="{!If(selected_Pricebook !=null,true,false)}">
<apex:pageBlockSection >
<apex:outputText value="{!selected_Pricebook}"/>
</apex:pageBlockSection>
</apex:pageBlock>

<apex:pageBlock title="Product Selection" rendered="{!If(selected_Pricebook !=null,true,false)}">
<br />

<apex:form >
Product Filter:
<apex:inputText id="filterValue" value="{!filterValue}" />
<apex:commandButton value="Filter" action="{!search}" rerender="out"/>
Enter characters to filter product selection.
<br /><br /><br />
</apex:form>

<apex:form >
<apex:pageblocktable id="allprod" value="{!Products}" var="allprod">
<apex:column headervalue="Select Product">
<apex:actionsupport action="{!useProduct}" event="onclick" rerender="out2">
<input type="radio" />
<apex:param name="selected_Product" value="{!allprod.Product2Id}">
</apex:param>
</apex:actionsupport>
</apex:column>
<apex:column headervalue="Product Code">
<apex:outputfield value="{!allprod.Name}">
</apex:outputfield></apex:column>
<apex:column headervalue="Product Code">
<apex:outputfield value="{!allprod.Product2.ProductCode}">
</apex:outputfield></apex:column>
<apex:column headervalue="Product Description">
<apex:outputfield value="{!allprod.Product2.Description}">
</apex:outputfield></apex:column>
</apex:pageblocktable>
</apex:form>
</apex:pageBlock>
<apex:outputPanel rendered="{! ProdError }">
<h1><div align="center">
There are no products that match the currency of this quote in this PriceBook?
</div></h1>
</apex:outputPanel>
</apex:outputPanel>

<apex:outputPanel id="out2" rendered="{!If(selected_Product !=null,true,false)}">
<p>You have selected:</p>
<apex:outputText value="{!selected_Product}"/>
</apex:outputPanel>

</apex:pageBlock>




Apex Controller



public class queryProduct {
//unit test ideas, need to add data into the fields via script and submit it seems
//https://developer.salesforce.com/forums/?id=906F0000000ALYKIA4


//Variables for working with the quote
public string quoteId;
public static List<Quote__c> myQuote;
//Variables for working with the pricebook
public String selected_Pricebook {get;set;}
public List<String> tmpString;// {get; set;}
public List<SelectOption> pricebook_name {get; set;}
public boolean ProdError { get; set; }
//Variables for working with the selected product
public string selected_Product {get;set;}
public string filterValue{get; set;}

public static List<Quote__c> getQuotedetails() {
string quoteId = ApexPages.currentPage().getparameters().get('Id');
System.debug( 'Quote Id is ' + quoteId);
myQuote = [SELECT Id, Name, Account__r.Name, Opportunity__r.Name, CurrencyIsoCode FROM Quote__c where Id =:quoteId];
system.debug(string.valueOf(myQuote));
return myQuote;
}
public queryProduct(){
//Getting list of price books to show user. This list from their user profile assignment.
pricebook_name = new List<SelectOption>();

tmpString = new List<String>();
User a = [SELECT PriceBooks__c
FROM User
WHERE Id =:UserInfo.getUserId()];
tmpString.addAll(a.PriceBooks__c.split(';'));
System.debug( 'Price books ' + tmpString);
for( String b : tmpString ) {
pricebook_name.add( new SelectOption( b, b ) );
}
}

public List<PricebookEntry> getProducts(){
//Getting the products in the selected price book
//Need to turn the string into and ID first.
System.debug( 'in getProducts, selected pricebook is: ' + selected_Pricebook);
List<Pricebook2> pId = [Select Id from PriceBook2 where Name=:selected_Pricebook limit 1];
List<PricebookEntry> productList;
String baseQuery = 'Select Name, Product2Id, Product2.ProductCode, Product2.Description,UnitPrice from PriceBookEntry where Pricebook2Id=''+pId[0].Id+'' and CurrencyIsoCode =''+myQuote[0].CurrencyIsoCode+''';
if( !string.ISBLANK(filterValue) ) {
string searchValue = ''%'+ filterValue +'%'';
baseQuery = baseQuery + 'and Name like '+searchValue;
}
System.debug( 'in getProducts, product list query is: ' + baseQuery);
productList = database.query(baseQuery);

//Is there products to return? or a blank result set?
if( productList.isEmpty() ) {
ProdError = TRUE;
} else {
ProdError = FALSE;
}
System.debug('ProdError status: '+ProdError);
System.debug('in getProducts prodlist var is: '+productList);
return productList;
}
public PageReference search(){
return null;
}
public PageReference useProduct(){
//Need that price book ID again.
List<Pricebook2> pId = [Select Id from PriceBook2 where Name=:selected_Pricebook limit 1];
System.debug( 'in useProduct stage, Price book is seen as - ' + pId );

String selected_Product = System.currentPagereference().getParameters().get('selected_Product');
System.debug( 'in useProduct and the selected_Product ' + selected_Product);

List<Product2> p = [select Description, ProductCode from Product2 WHERE Id=:selected_Product];
System.debug( 'in useProduct stage, Product query is - ' + p );
List<PricebookEntry> pb = [select UnitPrice from PricebookEntry WHERE Product2Id=:selected_Product and CurrencyIsoCode =:myQuote[0].CurrencyIsoCode];
System.debug( 'in useProduct stage, PriceBookEntry is - ' + pb );
//Create new quoted product record, now that all the data is collected
QuotedProduct__c qp = new QuotedProduct__c(Quote__c = myQuote[0].Id,
CurrencyIsoCode = myQuote[0].CurrencyIsoCode,
Price_Book__c = pId[0].Id,
Product__c = selected_Product,
ListPrice__c = pb[0].UnitPrice,
Starting_Price__c = pb[0].UnitPrice,
Quantity__c = 1,
ProductCode2__c = p[0].ProductCode,
ProductDescription2__c = p[0].Description
);
try{
insert qp;
} catch (System.DmlException e){
System.debug('ERROR: Creating the Quoted Product:' + e);
}
//Send user back to the new quoted Product record
PageReference pageRef = new PageReference('/' + qp.Id);
pageRef.setRedirect(true);
return pageRef;
}
public void clear(){
selected_Pricebook = null;
}}


Thanks,










share|improve this question






















  • The test class will be as good as any other test class that you may have written. In this case you will need to create test data to which will represent User input.
    – Jayant Das
    8 hours ago
















1














I have a process that has been built that presents a visualforce page to the user, they first select a price book, and a section on page is refreshed. They are presented with a list of products from that price book. Once they select a product, a record is created on the Quoted_Products__c custom object. This process works fine and my problem is I have no idea how to write a unit test for simulating user selections on the visualforce page.



I have no test code to show as I have no idea where start. Doing some Google Fu I am only finding how to create test users and to run a test as a user and the like. I am not seeing anything on how to simulate a user making selections. Do I just make some assumptions on user selection and then run the very last process that creates the records? If so, how to set the required variables into the test page environment?



Below is my Controller and the Visualforce page. Any pointers would be great.



Visualforce Page



<apex:page Controller="queryProduct"> 

<apex:pageBlock >
<apex:pageBlockSection title="Active Quote Detail">
<apex:pageBlockTable value="{! quotedetails }" var="qd">
<apex:column value="{! qd.Id }"/>
<apex:column value="{! qd.Name }"/>
<apex:column value="{! qd.Account__r.Name }"/>
<apex:column value="{! qd.CurrencyIsocode }"/>
</apex:pageBlockTable>
</apex:pageBlockSection>

<apex:pageBlockSection title="Pricebook selection">
<apex:form >
<apex:outputLabel value="Which Pricebook? :"/>
<apex:selectList value="{! selected_Pricebook}" size="1">
<apex:selectOptions value="{! pricebook_name}"/>
</apex:selectList>
<br /><br />
<apex:commandButton value="Show Products" action="{!search}" rerender="out"/>
<apex:commandButton value="Clear" action="{!clear}"/>
</apex:form>
</apex:pageBlockSection>

<apex:outputPanel id="out">
<apex:pageBlock title="Selected PriceBook" rendered="{!If(selected_Pricebook !=null,true,false)}">
<apex:pageBlockSection >
<apex:outputText value="{!selected_Pricebook}"/>
</apex:pageBlockSection>
</apex:pageBlock>

<apex:pageBlock title="Product Selection" rendered="{!If(selected_Pricebook !=null,true,false)}">
<br />

<apex:form >
Product Filter:
<apex:inputText id="filterValue" value="{!filterValue}" />
<apex:commandButton value="Filter" action="{!search}" rerender="out"/>
Enter characters to filter product selection.
<br /><br /><br />
</apex:form>

<apex:form >
<apex:pageblocktable id="allprod" value="{!Products}" var="allprod">
<apex:column headervalue="Select Product">
<apex:actionsupport action="{!useProduct}" event="onclick" rerender="out2">
<input type="radio" />
<apex:param name="selected_Product" value="{!allprod.Product2Id}">
</apex:param>
</apex:actionsupport>
</apex:column>
<apex:column headervalue="Product Code">
<apex:outputfield value="{!allprod.Name}">
</apex:outputfield></apex:column>
<apex:column headervalue="Product Code">
<apex:outputfield value="{!allprod.Product2.ProductCode}">
</apex:outputfield></apex:column>
<apex:column headervalue="Product Description">
<apex:outputfield value="{!allprod.Product2.Description}">
</apex:outputfield></apex:column>
</apex:pageblocktable>
</apex:form>
</apex:pageBlock>
<apex:outputPanel rendered="{! ProdError }">
<h1><div align="center">
There are no products that match the currency of this quote in this PriceBook?
</div></h1>
</apex:outputPanel>
</apex:outputPanel>

<apex:outputPanel id="out2" rendered="{!If(selected_Product !=null,true,false)}">
<p>You have selected:</p>
<apex:outputText value="{!selected_Product}"/>
</apex:outputPanel>

</apex:pageBlock>




Apex Controller



public class queryProduct {
//unit test ideas, need to add data into the fields via script and submit it seems
//https://developer.salesforce.com/forums/?id=906F0000000ALYKIA4


//Variables for working with the quote
public string quoteId;
public static List<Quote__c> myQuote;
//Variables for working with the pricebook
public String selected_Pricebook {get;set;}
public List<String> tmpString;// {get; set;}
public List<SelectOption> pricebook_name {get; set;}
public boolean ProdError { get; set; }
//Variables for working with the selected product
public string selected_Product {get;set;}
public string filterValue{get; set;}

public static List<Quote__c> getQuotedetails() {
string quoteId = ApexPages.currentPage().getparameters().get('Id');
System.debug( 'Quote Id is ' + quoteId);
myQuote = [SELECT Id, Name, Account__r.Name, Opportunity__r.Name, CurrencyIsoCode FROM Quote__c where Id =:quoteId];
system.debug(string.valueOf(myQuote));
return myQuote;
}
public queryProduct(){
//Getting list of price books to show user. This list from their user profile assignment.
pricebook_name = new List<SelectOption>();

tmpString = new List<String>();
User a = [SELECT PriceBooks__c
FROM User
WHERE Id =:UserInfo.getUserId()];
tmpString.addAll(a.PriceBooks__c.split(';'));
System.debug( 'Price books ' + tmpString);
for( String b : tmpString ) {
pricebook_name.add( new SelectOption( b, b ) );
}
}

public List<PricebookEntry> getProducts(){
//Getting the products in the selected price book
//Need to turn the string into and ID first.
System.debug( 'in getProducts, selected pricebook is: ' + selected_Pricebook);
List<Pricebook2> pId = [Select Id from PriceBook2 where Name=:selected_Pricebook limit 1];
List<PricebookEntry> productList;
String baseQuery = 'Select Name, Product2Id, Product2.ProductCode, Product2.Description,UnitPrice from PriceBookEntry where Pricebook2Id=''+pId[0].Id+'' and CurrencyIsoCode =''+myQuote[0].CurrencyIsoCode+''';
if( !string.ISBLANK(filterValue) ) {
string searchValue = ''%'+ filterValue +'%'';
baseQuery = baseQuery + 'and Name like '+searchValue;
}
System.debug( 'in getProducts, product list query is: ' + baseQuery);
productList = database.query(baseQuery);

//Is there products to return? or a blank result set?
if( productList.isEmpty() ) {
ProdError = TRUE;
} else {
ProdError = FALSE;
}
System.debug('ProdError status: '+ProdError);
System.debug('in getProducts prodlist var is: '+productList);
return productList;
}
public PageReference search(){
return null;
}
public PageReference useProduct(){
//Need that price book ID again.
List<Pricebook2> pId = [Select Id from PriceBook2 where Name=:selected_Pricebook limit 1];
System.debug( 'in useProduct stage, Price book is seen as - ' + pId );

String selected_Product = System.currentPagereference().getParameters().get('selected_Product');
System.debug( 'in useProduct and the selected_Product ' + selected_Product);

List<Product2> p = [select Description, ProductCode from Product2 WHERE Id=:selected_Product];
System.debug( 'in useProduct stage, Product query is - ' + p );
List<PricebookEntry> pb = [select UnitPrice from PricebookEntry WHERE Product2Id=:selected_Product and CurrencyIsoCode =:myQuote[0].CurrencyIsoCode];
System.debug( 'in useProduct stage, PriceBookEntry is - ' + pb );
//Create new quoted product record, now that all the data is collected
QuotedProduct__c qp = new QuotedProduct__c(Quote__c = myQuote[0].Id,
CurrencyIsoCode = myQuote[0].CurrencyIsoCode,
Price_Book__c = pId[0].Id,
Product__c = selected_Product,
ListPrice__c = pb[0].UnitPrice,
Starting_Price__c = pb[0].UnitPrice,
Quantity__c = 1,
ProductCode2__c = p[0].ProductCode,
ProductDescription2__c = p[0].Description
);
try{
insert qp;
} catch (System.DmlException e){
System.debug('ERROR: Creating the Quoted Product:' + e);
}
//Send user back to the new quoted Product record
PageReference pageRef = new PageReference('/' + qp.Id);
pageRef.setRedirect(true);
return pageRef;
}
public void clear(){
selected_Pricebook = null;
}}


Thanks,










share|improve this question






















  • The test class will be as good as any other test class that you may have written. In this case you will need to create test data to which will represent User input.
    – Jayant Das
    8 hours ago














1












1








1







I have a process that has been built that presents a visualforce page to the user, they first select a price book, and a section on page is refreshed. They are presented with a list of products from that price book. Once they select a product, a record is created on the Quoted_Products__c custom object. This process works fine and my problem is I have no idea how to write a unit test for simulating user selections on the visualforce page.



I have no test code to show as I have no idea where start. Doing some Google Fu I am only finding how to create test users and to run a test as a user and the like. I am not seeing anything on how to simulate a user making selections. Do I just make some assumptions on user selection and then run the very last process that creates the records? If so, how to set the required variables into the test page environment?



Below is my Controller and the Visualforce page. Any pointers would be great.



Visualforce Page



<apex:page Controller="queryProduct"> 

<apex:pageBlock >
<apex:pageBlockSection title="Active Quote Detail">
<apex:pageBlockTable value="{! quotedetails }" var="qd">
<apex:column value="{! qd.Id }"/>
<apex:column value="{! qd.Name }"/>
<apex:column value="{! qd.Account__r.Name }"/>
<apex:column value="{! qd.CurrencyIsocode }"/>
</apex:pageBlockTable>
</apex:pageBlockSection>

<apex:pageBlockSection title="Pricebook selection">
<apex:form >
<apex:outputLabel value="Which Pricebook? :"/>
<apex:selectList value="{! selected_Pricebook}" size="1">
<apex:selectOptions value="{! pricebook_name}"/>
</apex:selectList>
<br /><br />
<apex:commandButton value="Show Products" action="{!search}" rerender="out"/>
<apex:commandButton value="Clear" action="{!clear}"/>
</apex:form>
</apex:pageBlockSection>

<apex:outputPanel id="out">
<apex:pageBlock title="Selected PriceBook" rendered="{!If(selected_Pricebook !=null,true,false)}">
<apex:pageBlockSection >
<apex:outputText value="{!selected_Pricebook}"/>
</apex:pageBlockSection>
</apex:pageBlock>

<apex:pageBlock title="Product Selection" rendered="{!If(selected_Pricebook !=null,true,false)}">
<br />

<apex:form >
Product Filter:
<apex:inputText id="filterValue" value="{!filterValue}" />
<apex:commandButton value="Filter" action="{!search}" rerender="out"/>
Enter characters to filter product selection.
<br /><br /><br />
</apex:form>

<apex:form >
<apex:pageblocktable id="allprod" value="{!Products}" var="allprod">
<apex:column headervalue="Select Product">
<apex:actionsupport action="{!useProduct}" event="onclick" rerender="out2">
<input type="radio" />
<apex:param name="selected_Product" value="{!allprod.Product2Id}">
</apex:param>
</apex:actionsupport>
</apex:column>
<apex:column headervalue="Product Code">
<apex:outputfield value="{!allprod.Name}">
</apex:outputfield></apex:column>
<apex:column headervalue="Product Code">
<apex:outputfield value="{!allprod.Product2.ProductCode}">
</apex:outputfield></apex:column>
<apex:column headervalue="Product Description">
<apex:outputfield value="{!allprod.Product2.Description}">
</apex:outputfield></apex:column>
</apex:pageblocktable>
</apex:form>
</apex:pageBlock>
<apex:outputPanel rendered="{! ProdError }">
<h1><div align="center">
There are no products that match the currency of this quote in this PriceBook?
</div></h1>
</apex:outputPanel>
</apex:outputPanel>

<apex:outputPanel id="out2" rendered="{!If(selected_Product !=null,true,false)}">
<p>You have selected:</p>
<apex:outputText value="{!selected_Product}"/>
</apex:outputPanel>

</apex:pageBlock>




Apex Controller



public class queryProduct {
//unit test ideas, need to add data into the fields via script and submit it seems
//https://developer.salesforce.com/forums/?id=906F0000000ALYKIA4


//Variables for working with the quote
public string quoteId;
public static List<Quote__c> myQuote;
//Variables for working with the pricebook
public String selected_Pricebook {get;set;}
public List<String> tmpString;// {get; set;}
public List<SelectOption> pricebook_name {get; set;}
public boolean ProdError { get; set; }
//Variables for working with the selected product
public string selected_Product {get;set;}
public string filterValue{get; set;}

public static List<Quote__c> getQuotedetails() {
string quoteId = ApexPages.currentPage().getparameters().get('Id');
System.debug( 'Quote Id is ' + quoteId);
myQuote = [SELECT Id, Name, Account__r.Name, Opportunity__r.Name, CurrencyIsoCode FROM Quote__c where Id =:quoteId];
system.debug(string.valueOf(myQuote));
return myQuote;
}
public queryProduct(){
//Getting list of price books to show user. This list from their user profile assignment.
pricebook_name = new List<SelectOption>();

tmpString = new List<String>();
User a = [SELECT PriceBooks__c
FROM User
WHERE Id =:UserInfo.getUserId()];
tmpString.addAll(a.PriceBooks__c.split(';'));
System.debug( 'Price books ' + tmpString);
for( String b : tmpString ) {
pricebook_name.add( new SelectOption( b, b ) );
}
}

public List<PricebookEntry> getProducts(){
//Getting the products in the selected price book
//Need to turn the string into and ID first.
System.debug( 'in getProducts, selected pricebook is: ' + selected_Pricebook);
List<Pricebook2> pId = [Select Id from PriceBook2 where Name=:selected_Pricebook limit 1];
List<PricebookEntry> productList;
String baseQuery = 'Select Name, Product2Id, Product2.ProductCode, Product2.Description,UnitPrice from PriceBookEntry where Pricebook2Id=''+pId[0].Id+'' and CurrencyIsoCode =''+myQuote[0].CurrencyIsoCode+''';
if( !string.ISBLANK(filterValue) ) {
string searchValue = ''%'+ filterValue +'%'';
baseQuery = baseQuery + 'and Name like '+searchValue;
}
System.debug( 'in getProducts, product list query is: ' + baseQuery);
productList = database.query(baseQuery);

//Is there products to return? or a blank result set?
if( productList.isEmpty() ) {
ProdError = TRUE;
} else {
ProdError = FALSE;
}
System.debug('ProdError status: '+ProdError);
System.debug('in getProducts prodlist var is: '+productList);
return productList;
}
public PageReference search(){
return null;
}
public PageReference useProduct(){
//Need that price book ID again.
List<Pricebook2> pId = [Select Id from PriceBook2 where Name=:selected_Pricebook limit 1];
System.debug( 'in useProduct stage, Price book is seen as - ' + pId );

String selected_Product = System.currentPagereference().getParameters().get('selected_Product');
System.debug( 'in useProduct and the selected_Product ' + selected_Product);

List<Product2> p = [select Description, ProductCode from Product2 WHERE Id=:selected_Product];
System.debug( 'in useProduct stage, Product query is - ' + p );
List<PricebookEntry> pb = [select UnitPrice from PricebookEntry WHERE Product2Id=:selected_Product and CurrencyIsoCode =:myQuote[0].CurrencyIsoCode];
System.debug( 'in useProduct stage, PriceBookEntry is - ' + pb );
//Create new quoted product record, now that all the data is collected
QuotedProduct__c qp = new QuotedProduct__c(Quote__c = myQuote[0].Id,
CurrencyIsoCode = myQuote[0].CurrencyIsoCode,
Price_Book__c = pId[0].Id,
Product__c = selected_Product,
ListPrice__c = pb[0].UnitPrice,
Starting_Price__c = pb[0].UnitPrice,
Quantity__c = 1,
ProductCode2__c = p[0].ProductCode,
ProductDescription2__c = p[0].Description
);
try{
insert qp;
} catch (System.DmlException e){
System.debug('ERROR: Creating the Quoted Product:' + e);
}
//Send user back to the new quoted Product record
PageReference pageRef = new PageReference('/' + qp.Id);
pageRef.setRedirect(true);
return pageRef;
}
public void clear(){
selected_Pricebook = null;
}}


Thanks,










share|improve this question













I have a process that has been built that presents a visualforce page to the user, they first select a price book, and a section on page is refreshed. They are presented with a list of products from that price book. Once they select a product, a record is created on the Quoted_Products__c custom object. This process works fine and my problem is I have no idea how to write a unit test for simulating user selections on the visualforce page.



I have no test code to show as I have no idea where start. Doing some Google Fu I am only finding how to create test users and to run a test as a user and the like. I am not seeing anything on how to simulate a user making selections. Do I just make some assumptions on user selection and then run the very last process that creates the records? If so, how to set the required variables into the test page environment?



Below is my Controller and the Visualforce page. Any pointers would be great.



Visualforce Page



<apex:page Controller="queryProduct"> 

<apex:pageBlock >
<apex:pageBlockSection title="Active Quote Detail">
<apex:pageBlockTable value="{! quotedetails }" var="qd">
<apex:column value="{! qd.Id }"/>
<apex:column value="{! qd.Name }"/>
<apex:column value="{! qd.Account__r.Name }"/>
<apex:column value="{! qd.CurrencyIsocode }"/>
</apex:pageBlockTable>
</apex:pageBlockSection>

<apex:pageBlockSection title="Pricebook selection">
<apex:form >
<apex:outputLabel value="Which Pricebook? :"/>
<apex:selectList value="{! selected_Pricebook}" size="1">
<apex:selectOptions value="{! pricebook_name}"/>
</apex:selectList>
<br /><br />
<apex:commandButton value="Show Products" action="{!search}" rerender="out"/>
<apex:commandButton value="Clear" action="{!clear}"/>
</apex:form>
</apex:pageBlockSection>

<apex:outputPanel id="out">
<apex:pageBlock title="Selected PriceBook" rendered="{!If(selected_Pricebook !=null,true,false)}">
<apex:pageBlockSection >
<apex:outputText value="{!selected_Pricebook}"/>
</apex:pageBlockSection>
</apex:pageBlock>

<apex:pageBlock title="Product Selection" rendered="{!If(selected_Pricebook !=null,true,false)}">
<br />

<apex:form >
Product Filter:
<apex:inputText id="filterValue" value="{!filterValue}" />
<apex:commandButton value="Filter" action="{!search}" rerender="out"/>
Enter characters to filter product selection.
<br /><br /><br />
</apex:form>

<apex:form >
<apex:pageblocktable id="allprod" value="{!Products}" var="allprod">
<apex:column headervalue="Select Product">
<apex:actionsupport action="{!useProduct}" event="onclick" rerender="out2">
<input type="radio" />
<apex:param name="selected_Product" value="{!allprod.Product2Id}">
</apex:param>
</apex:actionsupport>
</apex:column>
<apex:column headervalue="Product Code">
<apex:outputfield value="{!allprod.Name}">
</apex:outputfield></apex:column>
<apex:column headervalue="Product Code">
<apex:outputfield value="{!allprod.Product2.ProductCode}">
</apex:outputfield></apex:column>
<apex:column headervalue="Product Description">
<apex:outputfield value="{!allprod.Product2.Description}">
</apex:outputfield></apex:column>
</apex:pageblocktable>
</apex:form>
</apex:pageBlock>
<apex:outputPanel rendered="{! ProdError }">
<h1><div align="center">
There are no products that match the currency of this quote in this PriceBook?
</div></h1>
</apex:outputPanel>
</apex:outputPanel>

<apex:outputPanel id="out2" rendered="{!If(selected_Product !=null,true,false)}">
<p>You have selected:</p>
<apex:outputText value="{!selected_Product}"/>
</apex:outputPanel>

</apex:pageBlock>




Apex Controller



public class queryProduct {
//unit test ideas, need to add data into the fields via script and submit it seems
//https://developer.salesforce.com/forums/?id=906F0000000ALYKIA4


//Variables for working with the quote
public string quoteId;
public static List<Quote__c> myQuote;
//Variables for working with the pricebook
public String selected_Pricebook {get;set;}
public List<String> tmpString;// {get; set;}
public List<SelectOption> pricebook_name {get; set;}
public boolean ProdError { get; set; }
//Variables for working with the selected product
public string selected_Product {get;set;}
public string filterValue{get; set;}

public static List<Quote__c> getQuotedetails() {
string quoteId = ApexPages.currentPage().getparameters().get('Id');
System.debug( 'Quote Id is ' + quoteId);
myQuote = [SELECT Id, Name, Account__r.Name, Opportunity__r.Name, CurrencyIsoCode FROM Quote__c where Id =:quoteId];
system.debug(string.valueOf(myQuote));
return myQuote;
}
public queryProduct(){
//Getting list of price books to show user. This list from their user profile assignment.
pricebook_name = new List<SelectOption>();

tmpString = new List<String>();
User a = [SELECT PriceBooks__c
FROM User
WHERE Id =:UserInfo.getUserId()];
tmpString.addAll(a.PriceBooks__c.split(';'));
System.debug( 'Price books ' + tmpString);
for( String b : tmpString ) {
pricebook_name.add( new SelectOption( b, b ) );
}
}

public List<PricebookEntry> getProducts(){
//Getting the products in the selected price book
//Need to turn the string into and ID first.
System.debug( 'in getProducts, selected pricebook is: ' + selected_Pricebook);
List<Pricebook2> pId = [Select Id from PriceBook2 where Name=:selected_Pricebook limit 1];
List<PricebookEntry> productList;
String baseQuery = 'Select Name, Product2Id, Product2.ProductCode, Product2.Description,UnitPrice from PriceBookEntry where Pricebook2Id=''+pId[0].Id+'' and CurrencyIsoCode =''+myQuote[0].CurrencyIsoCode+''';
if( !string.ISBLANK(filterValue) ) {
string searchValue = ''%'+ filterValue +'%'';
baseQuery = baseQuery + 'and Name like '+searchValue;
}
System.debug( 'in getProducts, product list query is: ' + baseQuery);
productList = database.query(baseQuery);

//Is there products to return? or a blank result set?
if( productList.isEmpty() ) {
ProdError = TRUE;
} else {
ProdError = FALSE;
}
System.debug('ProdError status: '+ProdError);
System.debug('in getProducts prodlist var is: '+productList);
return productList;
}
public PageReference search(){
return null;
}
public PageReference useProduct(){
//Need that price book ID again.
List<Pricebook2> pId = [Select Id from PriceBook2 where Name=:selected_Pricebook limit 1];
System.debug( 'in useProduct stage, Price book is seen as - ' + pId );

String selected_Product = System.currentPagereference().getParameters().get('selected_Product');
System.debug( 'in useProduct and the selected_Product ' + selected_Product);

List<Product2> p = [select Description, ProductCode from Product2 WHERE Id=:selected_Product];
System.debug( 'in useProduct stage, Product query is - ' + p );
List<PricebookEntry> pb = [select UnitPrice from PricebookEntry WHERE Product2Id=:selected_Product and CurrencyIsoCode =:myQuote[0].CurrencyIsoCode];
System.debug( 'in useProduct stage, PriceBookEntry is - ' + pb );
//Create new quoted product record, now that all the data is collected
QuotedProduct__c qp = new QuotedProduct__c(Quote__c = myQuote[0].Id,
CurrencyIsoCode = myQuote[0].CurrencyIsoCode,
Price_Book__c = pId[0].Id,
Product__c = selected_Product,
ListPrice__c = pb[0].UnitPrice,
Starting_Price__c = pb[0].UnitPrice,
Quantity__c = 1,
ProductCode2__c = p[0].ProductCode,
ProductDescription2__c = p[0].Description
);
try{
insert qp;
} catch (System.DmlException e){
System.debug('ERROR: Creating the Quoted Product:' + e);
}
//Send user back to the new quoted Product record
PageReference pageRef = new PageReference('/' + qp.Id);
pageRef.setRedirect(true);
return pageRef;
}
public void clear(){
selected_Pricebook = null;
}}


Thanks,







apex visualforce unit-test






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 9 hours ago









PHonnold

254




254












  • The test class will be as good as any other test class that you may have written. In this case you will need to create test data to which will represent User input.
    – Jayant Das
    8 hours ago


















  • The test class will be as good as any other test class that you may have written. In this case you will need to create test data to which will represent User input.
    – Jayant Das
    8 hours ago
















The test class will be as good as any other test class that you may have written. In this case you will need to create test data to which will represent User input.
– Jayant Das
8 hours ago




The test class will be as good as any other test class that you may have written. In this case you will need to create test data to which will represent User input.
– Jayant Das
8 hours ago










2 Answers
2






active

oldest

votes


















3














There are several distinctions here that can be made that I think will help clarify things for you.



You aren't really testing the Visualforce page itself



Testing what the user sees, and the flow through a page/wizard/etc... is less like unit testing, and more like functional testing. Tools like Selenium are built for that type of work, while test classes in Apex really aren't well suited.



Honestly, I'd suggest that you forget (for the most part) that a Visualforce page is involved at all.



Inputs from Visualforce are just a fancy way to set a variable



When you see something like the following in your Visualforce



<apex:selectList value="{! selected_Pricebook}" size="1">
<apex:selectOptions value="{! pricebook_name}"/>
</apex:selectList>


What you're doing is binding variables from your controller into the page (which allows Salesforce to render your page with dynamic data).



{!pricebook_name} here is an output (data flows from your controller, to the page), and {!selected_Pricebook} is an input (data flows from your page, into your controller).



Since Visualforce is just setting a value for the selected_Pricebook variable in your controller, you can "simulate" this by simply setting this variable programatically (i.e. through Apex). To Salesforce, there is very little/no difference between the two.



Focus on testing the logic in your controller



Your controller is just a class, much like any other.

Your controller has methods and variables, which are just like any other class.



Now, you'll probably need to step through a similar logic path that your users will end up taking (you need to make an instance of your controller, then set the pricebook name, then call getProducts(), etc...), but it really just is like testing any other apex class.




  • Set up your test data (the test environment)

  • Execute the one method that you want to test in this particular test method

  • Gather the data that results from you running the method under test, and make assertions to verify that the results are what you expect.


An example test method to help you on your way



@isTest
static void testGetQuoteDetails(){
// Phase 1: test setup
Pagereference testPage = Page.MyPageName;
testPage.getParameters().put('id', '<some id here>');
test.setCurrentPageReference(testPage);

QueryProduct testController = new QueryProduct();

// Phase 2: execution
Test.startTest();
List<Quote> results = testController.getQuoteDetails();
Test.stopTest();

// Phase 3: gather results and assert
System.assertNotEquals(true, results.isEmpty(), 'getQuoteDetails() should have returned at least one quote');
}





share|improve this answer





























    2














    You can simulate user interaction by directly setting the properties to which your Visualforce components' values are bound, and by directly invoking the action methods that they fire. You can then validate the behavior or state of your controller class by writing assertions. (It's actually quite a bit simpler to test a straightforward Visualforce page controller than you might think).



    For example, you can create a controller and directly set the value of your selected_Pricebook variable:



    queryProduct qp = new queryProduct();

    System.assertSomethingToShowThat(pricebook_name, isPopulatedCorrectlyForTestUser());

    qp.queryProduct = qp.pricebook_name[0].getValue();


    and then you can test further methods that are dependent on that user-populated variable, like getProducts().



    You can call actions directly as methods:



    PageReference pr = qp.search();
    System.assertEquals(null, pr, 'should return null to reload page');


    and subsequently validate any changes to the controller's state that those methods are expected to perform with further assertions.



    One area where I tend to find Visualforce testing a little more challenging or tricky than other Apex classes is that there's often a linear path of expected user interaction - i.e., the user will do this, then that, then the third thing.



    As a result, testing those interaction paths and the states through which the controller's expected to move can either product long, complex unit tests that are fragile because they try to test too many things (more like an integration test) or more unit-like tests that involve a great deal of setup to reach the desired state.



    This page is simple enough that I don't think that divide is going to be a major issue for you. You've got methods that have pretty straightforward state changes and entry expectations:





    • getQuoteDetails() has no side effects and just depends on a URL parameter. - search() has no side effects but returns null.


    • clear() just sets one controller variable.


    • useProduct() performs DML and depends on selected_Pricebook and a URL parameter.


    You should be able to write unit tests for these methods that create test data, set up the controller state as expected, perform the action, and validate the controller state afterwards without too much trouble.



    The only major difference between testing these methods and testing any other Apex that works on data in similar ways is that you'll have to populate the parameters on the current Page Reference from your test code.






    share|improve this answer





















    • looks like (along w/ derek's answer) a canonical-qa :-)
      – cropredy
      7 hours ago











    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "459"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f245374%2fhow-to-create-unit-test-for-apex-controller-that-responds-to-user-input%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3














    There are several distinctions here that can be made that I think will help clarify things for you.



    You aren't really testing the Visualforce page itself



    Testing what the user sees, and the flow through a page/wizard/etc... is less like unit testing, and more like functional testing. Tools like Selenium are built for that type of work, while test classes in Apex really aren't well suited.



    Honestly, I'd suggest that you forget (for the most part) that a Visualforce page is involved at all.



    Inputs from Visualforce are just a fancy way to set a variable



    When you see something like the following in your Visualforce



    <apex:selectList value="{! selected_Pricebook}" size="1">
    <apex:selectOptions value="{! pricebook_name}"/>
    </apex:selectList>


    What you're doing is binding variables from your controller into the page (which allows Salesforce to render your page with dynamic data).



    {!pricebook_name} here is an output (data flows from your controller, to the page), and {!selected_Pricebook} is an input (data flows from your page, into your controller).



    Since Visualforce is just setting a value for the selected_Pricebook variable in your controller, you can "simulate" this by simply setting this variable programatically (i.e. through Apex). To Salesforce, there is very little/no difference between the two.



    Focus on testing the logic in your controller



    Your controller is just a class, much like any other.

    Your controller has methods and variables, which are just like any other class.



    Now, you'll probably need to step through a similar logic path that your users will end up taking (you need to make an instance of your controller, then set the pricebook name, then call getProducts(), etc...), but it really just is like testing any other apex class.




    • Set up your test data (the test environment)

    • Execute the one method that you want to test in this particular test method

    • Gather the data that results from you running the method under test, and make assertions to verify that the results are what you expect.


    An example test method to help you on your way



    @isTest
    static void testGetQuoteDetails(){
    // Phase 1: test setup
    Pagereference testPage = Page.MyPageName;
    testPage.getParameters().put('id', '<some id here>');
    test.setCurrentPageReference(testPage);

    QueryProduct testController = new QueryProduct();

    // Phase 2: execution
    Test.startTest();
    List<Quote> results = testController.getQuoteDetails();
    Test.stopTest();

    // Phase 3: gather results and assert
    System.assertNotEquals(true, results.isEmpty(), 'getQuoteDetails() should have returned at least one quote');
    }





    share|improve this answer


























      3














      There are several distinctions here that can be made that I think will help clarify things for you.



      You aren't really testing the Visualforce page itself



      Testing what the user sees, and the flow through a page/wizard/etc... is less like unit testing, and more like functional testing. Tools like Selenium are built for that type of work, while test classes in Apex really aren't well suited.



      Honestly, I'd suggest that you forget (for the most part) that a Visualforce page is involved at all.



      Inputs from Visualforce are just a fancy way to set a variable



      When you see something like the following in your Visualforce



      <apex:selectList value="{! selected_Pricebook}" size="1">
      <apex:selectOptions value="{! pricebook_name}"/>
      </apex:selectList>


      What you're doing is binding variables from your controller into the page (which allows Salesforce to render your page with dynamic data).



      {!pricebook_name} here is an output (data flows from your controller, to the page), and {!selected_Pricebook} is an input (data flows from your page, into your controller).



      Since Visualforce is just setting a value for the selected_Pricebook variable in your controller, you can "simulate" this by simply setting this variable programatically (i.e. through Apex). To Salesforce, there is very little/no difference between the two.



      Focus on testing the logic in your controller



      Your controller is just a class, much like any other.

      Your controller has methods and variables, which are just like any other class.



      Now, you'll probably need to step through a similar logic path that your users will end up taking (you need to make an instance of your controller, then set the pricebook name, then call getProducts(), etc...), but it really just is like testing any other apex class.




      • Set up your test data (the test environment)

      • Execute the one method that you want to test in this particular test method

      • Gather the data that results from you running the method under test, and make assertions to verify that the results are what you expect.


      An example test method to help you on your way



      @isTest
      static void testGetQuoteDetails(){
      // Phase 1: test setup
      Pagereference testPage = Page.MyPageName;
      testPage.getParameters().put('id', '<some id here>');
      test.setCurrentPageReference(testPage);

      QueryProduct testController = new QueryProduct();

      // Phase 2: execution
      Test.startTest();
      List<Quote> results = testController.getQuoteDetails();
      Test.stopTest();

      // Phase 3: gather results and assert
      System.assertNotEquals(true, results.isEmpty(), 'getQuoteDetails() should have returned at least one quote');
      }





      share|improve this answer
























        3












        3








        3






        There are several distinctions here that can be made that I think will help clarify things for you.



        You aren't really testing the Visualforce page itself



        Testing what the user sees, and the flow through a page/wizard/etc... is less like unit testing, and more like functional testing. Tools like Selenium are built for that type of work, while test classes in Apex really aren't well suited.



        Honestly, I'd suggest that you forget (for the most part) that a Visualforce page is involved at all.



        Inputs from Visualforce are just a fancy way to set a variable



        When you see something like the following in your Visualforce



        <apex:selectList value="{! selected_Pricebook}" size="1">
        <apex:selectOptions value="{! pricebook_name}"/>
        </apex:selectList>


        What you're doing is binding variables from your controller into the page (which allows Salesforce to render your page with dynamic data).



        {!pricebook_name} here is an output (data flows from your controller, to the page), and {!selected_Pricebook} is an input (data flows from your page, into your controller).



        Since Visualforce is just setting a value for the selected_Pricebook variable in your controller, you can "simulate" this by simply setting this variable programatically (i.e. through Apex). To Salesforce, there is very little/no difference between the two.



        Focus on testing the logic in your controller



        Your controller is just a class, much like any other.

        Your controller has methods and variables, which are just like any other class.



        Now, you'll probably need to step through a similar logic path that your users will end up taking (you need to make an instance of your controller, then set the pricebook name, then call getProducts(), etc...), but it really just is like testing any other apex class.




        • Set up your test data (the test environment)

        • Execute the one method that you want to test in this particular test method

        • Gather the data that results from you running the method under test, and make assertions to verify that the results are what you expect.


        An example test method to help you on your way



        @isTest
        static void testGetQuoteDetails(){
        // Phase 1: test setup
        Pagereference testPage = Page.MyPageName;
        testPage.getParameters().put('id', '<some id here>');
        test.setCurrentPageReference(testPage);

        QueryProduct testController = new QueryProduct();

        // Phase 2: execution
        Test.startTest();
        List<Quote> results = testController.getQuoteDetails();
        Test.stopTest();

        // Phase 3: gather results and assert
        System.assertNotEquals(true, results.isEmpty(), 'getQuoteDetails() should have returned at least one quote');
        }





        share|improve this answer












        There are several distinctions here that can be made that I think will help clarify things for you.



        You aren't really testing the Visualforce page itself



        Testing what the user sees, and the flow through a page/wizard/etc... is less like unit testing, and more like functional testing. Tools like Selenium are built for that type of work, while test classes in Apex really aren't well suited.



        Honestly, I'd suggest that you forget (for the most part) that a Visualforce page is involved at all.



        Inputs from Visualforce are just a fancy way to set a variable



        When you see something like the following in your Visualforce



        <apex:selectList value="{! selected_Pricebook}" size="1">
        <apex:selectOptions value="{! pricebook_name}"/>
        </apex:selectList>


        What you're doing is binding variables from your controller into the page (which allows Salesforce to render your page with dynamic data).



        {!pricebook_name} here is an output (data flows from your controller, to the page), and {!selected_Pricebook} is an input (data flows from your page, into your controller).



        Since Visualforce is just setting a value for the selected_Pricebook variable in your controller, you can "simulate" this by simply setting this variable programatically (i.e. through Apex). To Salesforce, there is very little/no difference between the two.



        Focus on testing the logic in your controller



        Your controller is just a class, much like any other.

        Your controller has methods and variables, which are just like any other class.



        Now, you'll probably need to step through a similar logic path that your users will end up taking (you need to make an instance of your controller, then set the pricebook name, then call getProducts(), etc...), but it really just is like testing any other apex class.




        • Set up your test data (the test environment)

        • Execute the one method that you want to test in this particular test method

        • Gather the data that results from you running the method under test, and make assertions to verify that the results are what you expect.


        An example test method to help you on your way



        @isTest
        static void testGetQuoteDetails(){
        // Phase 1: test setup
        Pagereference testPage = Page.MyPageName;
        testPage.getParameters().put('id', '<some id here>');
        test.setCurrentPageReference(testPage);

        QueryProduct testController = new QueryProduct();

        // Phase 2: execution
        Test.startTest();
        List<Quote> results = testController.getQuoteDetails();
        Test.stopTest();

        // Phase 3: gather results and assert
        System.assertNotEquals(true, results.isEmpty(), 'getQuoteDetails() should have returned at least one quote');
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 8 hours ago









        Derek F

        19k31849




        19k31849

























            2














            You can simulate user interaction by directly setting the properties to which your Visualforce components' values are bound, and by directly invoking the action methods that they fire. You can then validate the behavior or state of your controller class by writing assertions. (It's actually quite a bit simpler to test a straightforward Visualforce page controller than you might think).



            For example, you can create a controller and directly set the value of your selected_Pricebook variable:



            queryProduct qp = new queryProduct();

            System.assertSomethingToShowThat(pricebook_name, isPopulatedCorrectlyForTestUser());

            qp.queryProduct = qp.pricebook_name[0].getValue();


            and then you can test further methods that are dependent on that user-populated variable, like getProducts().



            You can call actions directly as methods:



            PageReference pr = qp.search();
            System.assertEquals(null, pr, 'should return null to reload page');


            and subsequently validate any changes to the controller's state that those methods are expected to perform with further assertions.



            One area where I tend to find Visualforce testing a little more challenging or tricky than other Apex classes is that there's often a linear path of expected user interaction - i.e., the user will do this, then that, then the third thing.



            As a result, testing those interaction paths and the states through which the controller's expected to move can either product long, complex unit tests that are fragile because they try to test too many things (more like an integration test) or more unit-like tests that involve a great deal of setup to reach the desired state.



            This page is simple enough that I don't think that divide is going to be a major issue for you. You've got methods that have pretty straightforward state changes and entry expectations:





            • getQuoteDetails() has no side effects and just depends on a URL parameter. - search() has no side effects but returns null.


            • clear() just sets one controller variable.


            • useProduct() performs DML and depends on selected_Pricebook and a URL parameter.


            You should be able to write unit tests for these methods that create test data, set up the controller state as expected, perform the action, and validate the controller state afterwards without too much trouble.



            The only major difference between testing these methods and testing any other Apex that works on data in similar ways is that you'll have to populate the parameters on the current Page Reference from your test code.






            share|improve this answer





















            • looks like (along w/ derek's answer) a canonical-qa :-)
              – cropredy
              7 hours ago
















            2














            You can simulate user interaction by directly setting the properties to which your Visualforce components' values are bound, and by directly invoking the action methods that they fire. You can then validate the behavior or state of your controller class by writing assertions. (It's actually quite a bit simpler to test a straightforward Visualforce page controller than you might think).



            For example, you can create a controller and directly set the value of your selected_Pricebook variable:



            queryProduct qp = new queryProduct();

            System.assertSomethingToShowThat(pricebook_name, isPopulatedCorrectlyForTestUser());

            qp.queryProduct = qp.pricebook_name[0].getValue();


            and then you can test further methods that are dependent on that user-populated variable, like getProducts().



            You can call actions directly as methods:



            PageReference pr = qp.search();
            System.assertEquals(null, pr, 'should return null to reload page');


            and subsequently validate any changes to the controller's state that those methods are expected to perform with further assertions.



            One area where I tend to find Visualforce testing a little more challenging or tricky than other Apex classes is that there's often a linear path of expected user interaction - i.e., the user will do this, then that, then the third thing.



            As a result, testing those interaction paths and the states through which the controller's expected to move can either product long, complex unit tests that are fragile because they try to test too many things (more like an integration test) or more unit-like tests that involve a great deal of setup to reach the desired state.



            This page is simple enough that I don't think that divide is going to be a major issue for you. You've got methods that have pretty straightforward state changes and entry expectations:





            • getQuoteDetails() has no side effects and just depends on a URL parameter. - search() has no side effects but returns null.


            • clear() just sets one controller variable.


            • useProduct() performs DML and depends on selected_Pricebook and a URL parameter.


            You should be able to write unit tests for these methods that create test data, set up the controller state as expected, perform the action, and validate the controller state afterwards without too much trouble.



            The only major difference between testing these methods and testing any other Apex that works on data in similar ways is that you'll have to populate the parameters on the current Page Reference from your test code.






            share|improve this answer





















            • looks like (along w/ derek's answer) a canonical-qa :-)
              – cropredy
              7 hours ago














            2












            2








            2






            You can simulate user interaction by directly setting the properties to which your Visualforce components' values are bound, and by directly invoking the action methods that they fire. You can then validate the behavior or state of your controller class by writing assertions. (It's actually quite a bit simpler to test a straightforward Visualforce page controller than you might think).



            For example, you can create a controller and directly set the value of your selected_Pricebook variable:



            queryProduct qp = new queryProduct();

            System.assertSomethingToShowThat(pricebook_name, isPopulatedCorrectlyForTestUser());

            qp.queryProduct = qp.pricebook_name[0].getValue();


            and then you can test further methods that are dependent on that user-populated variable, like getProducts().



            You can call actions directly as methods:



            PageReference pr = qp.search();
            System.assertEquals(null, pr, 'should return null to reload page');


            and subsequently validate any changes to the controller's state that those methods are expected to perform with further assertions.



            One area where I tend to find Visualforce testing a little more challenging or tricky than other Apex classes is that there's often a linear path of expected user interaction - i.e., the user will do this, then that, then the third thing.



            As a result, testing those interaction paths and the states through which the controller's expected to move can either product long, complex unit tests that are fragile because they try to test too many things (more like an integration test) or more unit-like tests that involve a great deal of setup to reach the desired state.



            This page is simple enough that I don't think that divide is going to be a major issue for you. You've got methods that have pretty straightforward state changes and entry expectations:





            • getQuoteDetails() has no side effects and just depends on a URL parameter. - search() has no side effects but returns null.


            • clear() just sets one controller variable.


            • useProduct() performs DML and depends on selected_Pricebook and a URL parameter.


            You should be able to write unit tests for these methods that create test data, set up the controller state as expected, perform the action, and validate the controller state afterwards without too much trouble.



            The only major difference between testing these methods and testing any other Apex that works on data in similar ways is that you'll have to populate the parameters on the current Page Reference from your test code.






            share|improve this answer












            You can simulate user interaction by directly setting the properties to which your Visualforce components' values are bound, and by directly invoking the action methods that they fire. You can then validate the behavior or state of your controller class by writing assertions. (It's actually quite a bit simpler to test a straightforward Visualforce page controller than you might think).



            For example, you can create a controller and directly set the value of your selected_Pricebook variable:



            queryProduct qp = new queryProduct();

            System.assertSomethingToShowThat(pricebook_name, isPopulatedCorrectlyForTestUser());

            qp.queryProduct = qp.pricebook_name[0].getValue();


            and then you can test further methods that are dependent on that user-populated variable, like getProducts().



            You can call actions directly as methods:



            PageReference pr = qp.search();
            System.assertEquals(null, pr, 'should return null to reload page');


            and subsequently validate any changes to the controller's state that those methods are expected to perform with further assertions.



            One area where I tend to find Visualforce testing a little more challenging or tricky than other Apex classes is that there's often a linear path of expected user interaction - i.e., the user will do this, then that, then the third thing.



            As a result, testing those interaction paths and the states through which the controller's expected to move can either product long, complex unit tests that are fragile because they try to test too many things (more like an integration test) or more unit-like tests that involve a great deal of setup to reach the desired state.



            This page is simple enough that I don't think that divide is going to be a major issue for you. You've got methods that have pretty straightforward state changes and entry expectations:





            • getQuoteDetails() has no side effects and just depends on a URL parameter. - search() has no side effects but returns null.


            • clear() just sets one controller variable.


            • useProduct() performs DML and depends on selected_Pricebook and a URL parameter.


            You should be able to write unit tests for these methods that create test data, set up the controller state as expected, perform the action, and validate the controller state afterwards without too much trouble.



            The only major difference between testing these methods and testing any other Apex that works on data in similar ways is that you'll have to populate the parameters on the current Page Reference from your test code.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered 8 hours ago









            David Reed

            30.6k61746




            30.6k61746












            • looks like (along w/ derek's answer) a canonical-qa :-)
              – cropredy
              7 hours ago


















            • looks like (along w/ derek's answer) a canonical-qa :-)
              – cropredy
              7 hours ago
















            looks like (along w/ derek's answer) a canonical-qa :-)
            – cropredy
            7 hours ago




            looks like (along w/ derek's answer) a canonical-qa :-)
            – cropredy
            7 hours ago


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Salesforce Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f245374%2fhow-to-create-unit-test-for-apex-controller-that-responds-to-user-input%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            CARDNET

            Boot-repair Failure: Unable to locate package grub-common:i386

            濃尾地震