2

I'm not very experienced with Apex, but have the following page and controller which queries the name of an Account and returns it to my page.

<apex:page controller="myApplicationController">

   <apex:pageBlock >
      <apex:form >
         <p>First name: <apex:inputText value="{!FirstName}"></apex:inputText></p>
      </apex:form>
   </apex:pageBlock>

</apex:page>



public with sharing class myApplicationController{

    public Account a;
    public String firstName;

    public myApplicationController() {       
        a = [SELECT Name FROM Account WHERE Id=: 'XXXXXXXXXXX'];
    }


    public String getFirstName() {
        return a.Name;
    }


    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }


  } 

This basic stuff is working fine, I want to write a unit test for my controller. The following test is failing but I can't figure out why.

@isTest
public sharing with class myApplicationTest{

    @isTest
    static void testmyApplicationTest() {

        myApplicationController controller = new myApplicationController();

        controller = new myApplicationController(); 

        controller.getFirstName();
    }

}

Could anyone explain where the problem is here or where I'm going wrong?

Here is the error message:

System.QueryException: List has no rows for assignment to SObject
3
  • Not sure why you are hard coding an Id in the constructor, anyway for the issue try putting return a[0].Name; in the getFirstName() method
    – highfive
    Jun 12, 2014 at 10:19
  • Already tried that @highfive, got the following error when trying to save. Expression must be a list type: SOBJECT:Account
    – Daft
    Jun 12, 2014 at 10:22
  • So declare a as something like public List<Account> accounts; and work with the list in the controller.
    – highfive
    Jun 12, 2014 at 10:26

1 Answer 1

3

You're not passing an Account ID to the controller in your test method.

It looks like the ID is hard-coded in your page controller, if this is the case then the test method won't be able to see this account without enabling the test class to see all data:

@isTest(SeeAllData=true)

This is generally considered bad practice though, so I would create an Account record in the test class and then pass that Account to the controller in your test method (by passing the ID as a URL parameter, for example).

This is how that would look in your controller:

Id accountId = ApexPages.currentPage().getParameters().get('AccountId');

and then in your test method:

Account testAccount = new Account(LastName='Test');
insert testAccount;

ApexPages.currentPage().getParameters().put('AccountId', testAccount.Id);

Hope this helps;

5
  • 1
    Ah! Cheers @DavinC, I've hard-coded the Id for convenience, I didn't think it would affect the test at all!
    – Daft
    Jun 12, 2014 at 10:33
  • Could you possibly explain 'create an Account record in the test class' please?
    – Daft
    Jun 12, 2014 at 10:45
  • 1
    Well creating an Account in the test class will save you setting the SeeAllData parameter to true, which is generally the best practice for test classes. There's some good info here: laceysnr.com/2012/04/… Jun 12, 2014 at 10:48
  • Cheers man, appreciate the helpful response!
    – Daft
    Jun 12, 2014 at 10:51
  • No problem at all! Jun 12, 2014 at 10:53

You must log in to answer this question.

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