1

In my visualforce page I have a search field (inputText) with an id of 'query'. Query is passed into my controller and the runSearch() method starts a process which initiates a web service call. In my test class I am trying to initiate the API call by passing in a search value.

Extension

public with sharing class ClinicalStudySetupExtension {

private String studyJson;
private String result;
private String protocolNumber;
public String query {get; set;}
public Boolean searched {get; set;}
public Clinical_Study__c cStudy {get; set;}
private ApexPages.StandardController std {get; set;}

//controller
public ClinicalStudySetupExtension(ApexPages.StandardController std) {

    this.std = std;
    this.studyJson = callRestEndPoint();

    query = '';
    searched=false;
    String queryStr=ApexPages.currentPage().getParameters().get('query');
    if (queryStr!=null)
    {
        protocolNumber=queryStr;
        runSearch();
    }
}

public pageReference runSearch() {//runSearch takes the input 'query' and passes it to the REST api call

    searched=true;
    String searchStr = ''+query+'';
    system.debug('Study name: ' + query);
    protocolNumber = searchStr.deleteWhitespace();

    this.studyJson = callRestEndPoint();

    return null;
  }

private string callRestEndPoint() {//the rest api call generates a json string and passes it to the json parser      
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();

    String username = 'ex';
    String password = 'ex';

    Blob headerValue = Blob.valueOf(username + ':' + password);
    String authorizationHeader = 'Basic ' + EncodingUtil.base64Encode(headerValue);
    req.setClientCertificateName('CN');
    req.setHeader('Authorization', authorizationHeader);
    req.setHeader('Api-Key', '777..');
    req.setTimeout(120000);

    req.setMethod('GET');
    req.setEndpoint('https://example.com/study/'+protocolNumber);      

    String result = '';
    try{
        res = h.send(req);
        result = res.getBody();
        }
    catch(System.CalloutException e){
        result = res.toString();
        }

    return result;     
}

List<StudyWrapper> Study = new List<StudyWrapper>();

public List<StudyWrapper> getStudy(){//the json parser parses the json string and puts it in a list, study
    JSONParser parser = JSON.createParser(this.studyJson);
    while(parser.nextToken() != null){
            while(parser.nextToken()!= null){
                if(parser.getCurrentToken()==JSONToken.START_OBJECT){
                    StudyWrapper s = (StudyWrapper)parser.readValueAs(StudyWrapper.class);
                    Study.add(s);
                }
            }
        }
    return Study;
}

I'm trying to set up my test class, so far it looks like this:

Test class

static testMethod void testRunSearch(){

    //create a test user
    Profile p1 = [SELECT Id FROM Profile WHERE Name='System Administrator'];

    User u1 = new User(Alias = 'George', UserName='JFFGeo@testorg#.com', Email='[email protected]', LastName='George', ProfileId = p1.Id, EmailEncodingKey='UTF-8',  LanguageLocaleKey='en_US', LocaleSidKey='en_US', TimeZoneSidKey='America/Los_Angeles' );
    insert u1;

    //Arrange the components
    PageReference pageRef = Page.ClinicalStudySetup;

    Test.setCurrentPage(pageRef);

    ApexPages.StandardController sc = new ApexPages.StandardController(new Clinical_Study__c());
    ClinicalStudySetupExtension ext = new ClinicalStudySetupExtension(sc);

    pageRef.getParameters().put('query','GA00806'); 

    Test.startTest();

        System.runAs(u1){

            ext.runSearch();

        }

    Test.stopTest();

}

Unfortunately, the way that I'm defining query and executing runSearch() doesn't seem to be working in my test class. The method isn't even being hit when I run my test class. Can someone tell me, what am I doing wrong? Or what could be the cause of this?

1
  • Are you creating test data - unit tests by default don't have access to system data, it needs to be created. Therefore it may be that the record 'GA00806' is not visible from the test context.
    – Jim
    Feb 18, 2015 at 22:30

3 Answers 3

1

In your test class you need to call put method, instead of get method

 ApexPages.currentPage().getParameters().put('query',yourString);

Is this what you are looking for? Documentation

9
  • Thanks Mihai, I think my question may have been wrong, I've updated it
    – rwegner7
    Feb 18, 2015 at 22:57
  • I'm not really sure where you have the problem. The way you have it now, with the put method should populate the string query when you create the extension in your test. Unless I misunderstood your problem. Feb 18, 2015 at 23:04
  • I'm not sure where the error is either. The line for my runSearch method doesn't even get looked at when I run the test.
    – rwegner7
    Feb 18, 2015 at 23:18
  • The test doesn't cover the runSearch method ? Or you don't get the expected result when you call the method? Also there is no need to insert the user, runAs method will insert it for you and it won't count towards your licence. Feb 18, 2015 at 23:24
  • thanks MIhai, I'll remove the runAs. The runSearch method doesn't get covered at all, which is really baffling me
    – rwegner7
    Feb 18, 2015 at 23:37
1

You need to create your test data e.g.

Clinical_Study__c clinicalStudy = new Clinical_Study__c();
clinicalStudy.Name = 'GA00806'; 
insert clinicalStudy; 

PageReference pageRef = Page.ClinicalStudySetup;
pageRef.getParameters().put('query', 'GA00806'); 
Test.setCurrentPage(pageRef);

ClinicalStudySetupExtension cse = new ClinicalStudySetupExtension(new 

ApexPages.StandardController(ClinicalStudy));
//Act
cse.runSearch();

A good habit is to place all test method data creation into a separate test helper class - this way you just call the method whenever you need test data created, a simple example :

public class TestDataHelper() 
{
 public static List<Contact> createTestContacts(Int numRec) {
  List<Contact> conts = new List<Contact>(); 
  for(Integer i = 0; i < numRec; i++) {
  Contact testCont = new Contact(); 
  testCont.FirstName = 'fName' + i; 
  testCont.LastName = 'lName' + i; 
  conts.add(testCont); 
  }
  return conts; 
 }
}
2
  • Other than creating a user to run the test, there shouldn't be any other test data. What happens is the 'query' term in inputted, and then runSearch() does an api callout to get data
    – rwegner7
    Feb 18, 2015 at 22:38
  • Righto - your controller would be helpful also. you should have 'pageRef.getParameters().put('query','GA00806');' before the line 'Test.setCurrentPage(pageRef);'
    – Jim
    Feb 18, 2015 at 23:03
0

It was really stupid of me, the reason the test wasn't running my REST method was because it was because the extension was an http callout. I was getting an error message "FATAL_ERROR|System.TypeException: Methods defined as TestMethod do not support Web service callouts, test skipped". My whole test wasn't running.

What ended up being the solution was this great post by Meta Daddy on doing http callout tests. After that, everything fell into place.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .