0

This issue is connected with this post: MIXED_DML_OPERATION, DML operation error when creating user role record in test class but I've decided to post this as another topic since this is a much different issue.

This includes UserRole object wherein selected role name must be assigned to a field in Setting__c custom setting.

I hope that this would not be tagged as duplicate as this is different from other posts I've seen, and as I am just seeking for some help.

Please bear with me, and thanks in advance.

I encounter this error after I run the test class:

List has no rows for assignment to SObject

Error pertains to this line of codes:

UserRole ur = [SELECT Id, Name FROM UserRole WHERE Id =: selectedRole]; from the controller and

to this line of code: uadc2.save(); from the test class itself.

How can I resolve this?

Apex Class:

public class SettingClass {

    private ApexPages.StandardController con;
    public Setting__c settingRec {get;set;}
    public List<SettingWrapper> swraplist {get;set;} 
    public Integer rowToRemove {get;set;}
    public String selectedRole {get;set;}
    public String selectedStat {get;set;}

    public SettingClass(ApexPages.StandardController controller) {
        con = controller;
        this.settingRec = (Setting__c)controller.getRecord();
        swraplist = new List<SettingWrapper>();
        addNewRow();

    }
    public void addNewRow() {
        List<SettingWrapper> temp_wrap = new List<SettingWrapper>();
        SettingWrapper newSetting = new SettingWrapper();

        Item__c newItemRecord = new Item__c();      
        newSetting.set1 = newItemRecord;
        newSetting.index = temp_wrap.size();
        temp_wrap.add(newSetting);
        for(SettingWrapper sw : temp_wrap) {
            swraplist.add(sw);
        }
    }

    public void removeRow() {
        List<SettingWrapper> rem_wrap = new List<SettingWrapper>();
        for(SettingWrapper sw : swraplist) {
            rem_wrap.add(sw);
        }
        rem_wrap.remove(rowToRemove);
        swraplist.clear();
        for(SettingWrapper sw2 : rem_wrap) {
            swraplist.add(sw2);
        }
    }

    public List<SelectOption> getUserRoleList() {
        List<UserRole> urList = [SELECT Id, Name FROM UserRole];
        List<SelectOption> urOptionList = new List<SelectOption>();
        urOptionList.add(new SelectOption(' ',' '));

        for(UserRole ur : urList) {
            urOptionList.add(new SelectOption(ur.Id, ur.Name));    
        }

        return urOptionList;
    }

    public List<SelectOption> getStatList() {
        List<SelectOption> statOptionList = new List<SelectOption>();
        Schema.DescribeFieldResult statResults = Account.Status__c.getDescribe();

        List<Schema.PicklistEntry> ple = statResults.getPicklistValues();

        for(Schema.PicklistEntry f : ple) {
            statOptionList.add(new SelectOption(f.getLabel(), f.getValue()));    
        }  

        return statOptionList;
    }

    public PageReference save() {

        List<SettingWrapper> swList = new List<SettingWrapper>();
        List<Item__c> newItemList = new List<Item__c>();


        for(SettingWrapper sw : swraplist) {
            swList.add(sw);
        }

        UserRole ur = [SELECT Id, Name FROM UserRole WHERE Id =: selectedRole];  

        Setting__c newSetting = new Setting__c();

        newSetting.Name = settingRec.Name;
        newSetting.Status__c = selectedStat;
        newSetting.Role_ID__c = selectedRole;
        newSetting.Role_Name__c = ur.Name;

        insert newSetting;

        if(swList !=null && !swList.isEmpty()) {

            for(SettingWrapper sRec : swList) {

                Item__c iTemp = new Item__c();
                iTemp.Lookup__c = iTemp.set1.Lookup__c; 
                iTemp.Setting__c = newSetting.Id; 
                newItemList.add(iTemp);
            }
        }

        if(!newItemList.isEmpty()) {
                insert newItemList;
        }    

        PageReference pageref = new PageReference('/' + newSetting.Id);
        pageref.setRedirect(true);
        return pageref;
    }

    public class SettingWrapper {

        public Integer index {get;set;}
        public Setting__c set1 {get;set;}

    }

}

Visualforce Page:

<apex:page standardController="Setting__c" extensions="SettingClass">
    <apex:sectionHeader title="Setting__c" subtitle="New Setting"/>
    <apex:pageMessages /> 
    <apex:form >

        <apex:pageBlock title="Setting" mode="edit">

            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}" />                 
            </apex:pageBlockButtons>

            <apex:pageBlockSection columns="2">

                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Name"/>
                    <apex:inputField value="{!settingRec.Name}"/>                 
                </apex:pageBlockSectionItem>  
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Role Name"/>
                    <apex:selectList value="{!selectedRole}" size="1">
                        <apex:selectOptions value="{!UserRoleList}"/> 
                    </apex:selectList>                 
                </apex:pageBlockSectionItem>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="Status"/>
                    <apex:selectList value="{!selectedStat}" size="1">
                        <apex:selectOptions value="{!StatList}"/> 
                    </apex:selectList>                 
                </apex:pageBlockSectionItem>

            </apex:pageBlockSection>

            <apex:pageBlockSection title="Items" columns="1">
                <apex:outputPanel id="tablepanel">
                <apex:variable value="{!0}" var="rowNum"/>
                    <apex:pageBlockTable value="{!swraplist}" var="s">

                        <apex:column headerValue="Action" style="width:80px">
                            <apex:commandLink value="Remove" style="color:red" action="{!removeRow}" rendered="{!rowNum > 0}" rerender="tablepanel" immediate="true" > 
                                <apex:param value="{!rowNum}" name="rowToRemove" assignTo="{!rowToRemove}"/>
                            </apex:commandLink>
                            <apex:variable var="rowNum" value="{!rowNum + 1}"/>
                        </apex:column>

                        <apex:column headerValue="Survey Summary Form" >
                            <apex:inputField value="{!s.set1.Lookup__c}"/>
                        </apex:column>

                    </apex:pageBlockTable>

                <apex:commandButton value="Add Item" action="{!addNewRow}" rerender="tablepanel"/>
                </apex:outputPanel>  
            </apex:pageBlockSection>

        </apex:pageBlock>

    </apex:form> 

</apex:page>

Test Class:

@isTest
public class SettingClassTest {
    private static testMethod void InsertSettingRecord() {

        List<Setting__c> settingList = new List<Setting__c>();
        List<SettingClass.SettingWrapper> settingWrapper = new List<SettingClass.SettingWrapper>();
        Integer rowToRemove = 0;
        String selectedRole;

        SettingClass sc = new SettingClass(new ApexPages.StandardController(new Setting__c()));

        sc.getUserRoleList();
        con.getStatList();

        UserRole urole;
        System.runAs(new User(Id=UserInfo.getUserId()) {
          urole = new UserRole();
          urole.Name = 'New Role';
          insert urole;
        }

        selectedRole = urole.Id;

        List<Lookup__c> lookupList = new List<Lookup__c>();
        Lookup__c lk = new Lookup__c();
        lk.Name = 'Lookup 1';
        lookupList.add(lk);

        insert lookupList;
        System.assertequals(lookupList + '', 'lookupList');

        Test.startTest();

        Setting__c s = new Setting__c();
        s.Name = '1';
        s.Status__c = 'Status 1';
        s.Role_ID__c = selectedRole; 
        s.Role_Name__c = urole.Name;
        settingList.add(s);

        insert settingList;   
        System.assertequals(settingList + '', 'settingList');

        PageReference pg = Page.SettingPage;
        Test.setCurrentPage(pg);
        ApexPages.StandardController pgCon = new ApexPages.StandardController(ad); 
        SettingClass sClass = new SettingClass(pgCon);

        sClass.addNewRow(); 
        sClass.rowToRemove = 1;
        sClass.removeRow();

        SettingClass.SettingWrapper setWrap = new SettingClass.SettingWrapper();

        for(Integer i=0; i<200; i++) {
            Item__c newItem = new Item__c();
            newItem.Lookup__c = lk.Id;
            newItem.Setting__c = s.Id;    
            setWrap.set1 = newItem;
            setWrap.index = 0;
            settingWrapper.add(setWrap);
        }

        PageReference pg1 = Page.SettingPage;
        Test.setCurrentPage(pg1); 
        ApexPages.StandardController pgCon1 = new ApexPages.StandardController(ad);
        SettingClass sClass2 = new SettingClass(pgCon1);

        for(SettingClass.SettingWrapper setWrap2 : settingWrapper) {
            sClass2.swraplist.remove(0);
            sClass2.swraplist.add(swrap);
        }

        sClass2.save(); 

        Test.stopTest();
    }   

}
2

1 Answer 1

2

This error always occurs when you directly assign the result of a query to a single Sobject variable, and the query returns no results.

To prevent the exception, simply assign to a List:

List<UserRole> ur = [SELECT Id, Name FROM UserRole WHERE Id =: selectedRole];

And then check the size of the returned list to determine how to proceed, and report errors to the user appropriately.

You should also check selectedRole for nullity, since it's under user control.

Now that's the exception as such. You have a different issue here that's the root cause: you're never assigning the selectedRole instance variable in your controller. You only assign it to a local variable in your test class and a field in your custom setting, so it's null when the query goes off.

2
  • 1
    Great! Just the explanation I need. Thank you so much David for your help :))
    – curdual
    Commented Mar 19, 2018 at 13:31
  • 1
    @curdual Can I just chime in and say that I would define selectedRole as an Id, not a String. While it is, technically, a String, the system will ensure that the value of selectedRole is always fitting the Id constraints (length, etc) so I tend to define IDs as such. Maybe I'm nit-picking, but it's just what I do. Commented Mar 19, 2018 at 18:37

You must log in to answer this question.

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