I have what I think is a simple controller and test class, but when I try to compile the test class, I get an error related to my deleteAddress() method:

System.QueryException: List has no rows for assignment to SObject

Is there something I am missing in my test class?

Edit: I've changed by test class (updated below) as follows: -- Moved Test.startTest(); to after the insert of testAcctAddr -- Added 3 new lines to assign the DelAddrId (24-26) -- Added an assertion at line 29

I am still getting the same error where the DelAddrId is not being populated for the deleteAddress method in my controller.

Test Class:

    private class Test_AcctAddressesController {
        static testMethod void testMethod1() 
            Account testAccount = test_CreateRecords.createAcct(0);
            insert testAccount;
            Contact testContact = test_CreateRecords.createCont(testAccount.Id);
            insert testContact;
            Account_Addresses__c testAcctAddr = new Account_Addresses__c();
                testAcctAddr.Account__c = testAccount.Id;
                testAcctAddr.Street__c = '1010 Test Ave';
                testAcctAddr.City__c = 'New York';
                testAcctAddr.State__c = 'NY';
                testAcctAddr.Zip_Postal_Code__c = '11212';
                testAcctAddr.Country__c = 'USA';
                testAcctAddr.Primary__c = TRUE;
                testAcctAddr.Current__c = TRUE;
            insert testAcctAddr;
        PageReference testPage = Page.Acct_Addresses;
            testPage.getParameters().put('DelAddrId', String.valueOf(testAcctAddr.Id));   
            ApexPages.StandardController AcctAdd = new ApexPages.standardController(testAccount);
                AcctAddresses AcctAdd1 = new AcctAddresses(AcctAdd);


    public class AcctAddresses {     
        public List<Account_Addresses__c> addresses{get;set;}
        public string DelAddrId { get; set;}
        public Account accounts {get;set;} 
        public Account acct {get;set;} 
        public AcctAddresses(ApexPages.StandardController controller) { 
            acct = (account)controller.getRecord();      
            accounts = [SELECT Id
                        FROM account
                        WHERE id=: acct.id LIMIT 1]; 
            addresses = [SELECT Id, Primary__c, Current__c, Street__c, City__c, State__c, Zip_Postal_Code__c, Country__c, Account__c
                        FROM Account_Addresses__c
                        WHERE Account__r.Id = :accounts.id ORDER BY Primary__c, State__c];     
    //This method is to edit the existing contact record while clicking the Edit link 
            public pageReference Save(){
                update addresses;
            return ApexPages.CurrentPage();
    //This method is to delete the contact record while clicking the Del link 
        public pageReference deleteAddress(){
            Account_addresses__c ToBeDeleted = [SELECT Id FROM Account_addresses__c WHERE id = : DelAddrId LIMIT 1]; 
                delete ToBeDeleted; 
                    String baseUrl = URL.getSalesforceBaseUrl().toExternalForm(); 
                    PageReference redirectPage = new PageReference(baseUrl+'/'+acct.id); 
                return redirectPage;  
  • Are you sure you're getting a QueryException at compile time and not when you run the test? DelAddrId is null by default, you'll need to set it before calling deleteAddress(), otherwise you will always get that exception because you're searching for a record that can't exist.
    – nbrown
    Commented Sep 9, 2020 at 19:52

2 Answers 2


You're trying to run the following query

[SELECT Id FROM Account_addresses__c WHERE id = : DelAddrId LIMIT 1]

But ask yourself, are you setting delAddrId anywhere in your test method?
Does any other code you're executing set that property?

If the answer to both of those questions is "no" (and that is indeed the case here), then you have a problem.

Remember, in a unit test, you are responsible for making sure that all of the data that the code you're testing needs to be able to run is set up and in place.

Setting delAddrId somewhere (in the code you're testing or, more likely, in a test method) should alleviate most of the issue here, but there's more you should be thinking about:

  • Assigning the result of a query to a single SObject carries some risk (it can result in the error you're currently seeing). It led you (well, us) to discover a different issue in your code, but generally you should be assigning the result of a query to a List
  • You aren't making any assertions. Assertions are one of the most important parts of a unit test. Without assertions, you don't know if your code is behaving appropriately. You could have a method called twoPlusTwo() that returns 5 instead of 4. You should make assertions against the results/output of the code your test method is testing. In this case, you are trying to delete a record, so your assertion should query for the Id of the record you wanted to delete to make sure that it actually was deleted
  • You don't have enough test methods. Coverage is nice, but a good test class doesn't necessarily focus on that. Instead, it will test many different scenarios, both positive and negative. A "positive" test would be something like "if I ask for this record to be deleted, is it actually deleted?". A "negative" test would be something like "if I fail to provide an Id to delete, does my code crash, throw an exception that is not caught, or does it handle the situation without failing?". By testing enough scenarios, your coverage will naturally be high.

Also, you don't need to query to update or delete a record. Having the Id is enough. delete new MyObject__c(Id = '012000000000123'); is enough to get the job done.

  • Thanks Derek. I know the test is flawed. I was just trying to get it to cover initially and then break it down into components. For the delete, don't I still need to call the deleteAddress method from my controller?
    – J. Neilan
    Commented Sep 9, 2020 at 21:06
  • @J.Neilan Yes, you do. You'd need to do something like AcctAdd1.delAddrId = testAcctAddr.Id; in your test class before you try calling the deleteAddress() method in your controller being tested (the "system under test", or SUT). In other words, you need to make sure the data you need is available/in place before you need it. David's (and my) suggestion to just use the Id instead of querying for the record is a suggestion that you'd apply to the deleteAddress() method itself.
    – Derek F
    Commented Sep 9, 2020 at 21:47
  • I tried that both ways (AcctAdd1.delAddrId = testAcctAddr.Id & AcctAdd1.delAddrId = 'a221h000001iCRxAAM' but I still get the same error when calling the deleteAddress method.
    – J. Neilan
    Commented Sep 9, 2020 at 22:14
  • @J.Neilan At this point, it might be helpful to edit your question to add a bit in a new section (don't overwrite the details in the question you have right now, append additional information) about the changes you've made based on David's and my answers. Also, please be sure to specify whether you've made the changes to your SUT, your test method, or both.
    – Derek F
    Commented Sep 9, 2020 at 22:55
  • Thanks Derek. I added the additional edits above and I am still getting the same error. Any additional advice would be appreciated.
    – J. Neilan
    Commented Sep 10, 2020 at 13:05

You are not populating DelAddrId, so it's null. When you run this query

Account_addresses__c ToBeDeleted = [SELECT Id FROM Account_addresses__c WHERE id = : DelAddrId LIMIT 1]; 

there are no matching records, so you get an exception since you're assigning to a single sObject instance.

You don't need to query here - you can just do delete new Account_Addresses__c(Id = DelAddrId) - but you do need to populate the Id value.

  • Thanks David. That makes sense, but don't I need to call the "deleteAddress" method in my controller in order to test it?
    – J. Neilan
    Commented Sep 9, 2020 at 21:05
  • Yes, you do need to call the method.
    – David Reed
    Commented Sep 9, 2020 at 21:07
  • I populated the DelAddrId and added the line you provided, but when I call the method to deleteAddress, it still has no rows. I'm not sure how to assign the delete ID to that method.
    – J. Neilan
    Commented Sep 9, 2020 at 21:19
  • You just need to assign to that property of the controller in your unit tests.
    – David Reed
    Commented Sep 9, 2020 at 21:51

You must log in to answer this question.

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