Apex测试类调用CheckingClass的listObjects属性问题
Hey there, let's break down why your test class isn't pulling values from the listObjects property in CheckingClass, and walk through the fixes step by step:
First, the Root Causes
- No Test Data Available: Your test class uses
SeeAllData=false(which is the right practice to avoid relying on production data), but the privategetListObjects()method pulls data directly from the database. Since the test sandbox has no data by default, this method returns nothing. - Private Method Limitation:
getListObjects()is private, so you can't call or override it directly in your test class to simulate results—unless you refactor for testability.
Solution 1: Insert Test Data Before Running the Test
The simplest fix is to create and insert test records that getListObjects() would query. Let's assume getListObjects() fetches Account records (adjust to match your actual object):
@isTest(SeeAllData=false) private class CheckingClassTest { @isTest static void test_method(){ // Step 1: Create and insert test records List<Account> testAccounts = new List<Account>{ new Account(Name='Test Account 1'), new Account(Name='Test Account 2') }; insert testAccounts; // Step 2: Initialize your CheckingClass instance CheckingClass testInstance = new CheckingClass(); // Step 3: Access the listObjects property to trigger the get method String result = testInstance.listObjects; // Step 4: Validate the result System.assertNotEquals(null, result, 'listObjects should not be null'); // Add more specific assertions based on what getListObjects() returns } }
Solution 2: Refactor for Test Isolation (Mocking)
If getListObjects() has complex logic or depends on other services, mocking is a better approach. We'll use dependency injection to replace the database call with a mock in tests:
Step 1: Refactor the Original Class
public with sharing class CheckingClass{ // Define an interface to encapsulate data retrieval logic public interface IObjectListProvider { String getListObjects(); } // Default implementation (uses your original private method logic) private class DefaultObjectListProvider implements IObjectListProvider { public String getListObjects(){ // Replace with your actual database query and string formatting logic List<Account> accList = [SELECT Id, Name FROM Account LIMIT 10]; String result = ''; for(Account acc : accList){ result += acc.Name + ','; } return result.removeEnd(','); } } public String listObjects{ get{ if(String.isEmpty(listObjects)){ listObjects = objectProvider.getListObjects(); } return listObjects; } set; } private IObjectListProvider objectProvider; // Default constructor for production use public CheckingClass(){ this.objectProvider = new DefaultObjectListProvider(); } // Constructor for tests to inject mock implementations public CheckingClass(IObjectListProvider provider){ this.objectProvider = provider; } }
Step 2: Write the Test with Mock
@isTest(SeeAllData=false) private class CheckingClassTest { @isTest static void test_method_with_mock(){ // Create a mock implementation to return predefined data CheckingClass.IObjectListProvider mockProvider = new CheckingClass.IObjectListProvider(){ public String getListObjects(){ return 'MockAccount1,MockAccount2'; } }; // Initialize the class with the mock CheckingClass testInstance = new CheckingClass(mockProvider); // Access the property and validate String result = testInstance.listObjects; System.assertEquals('MockAccount1,MockAccount2', result, 'Mocked data should match expected value'); } }
Quick Check: Ensure getListObjects() Returns Non-Empty
Double-check that getListObjects() doesn't return an empty string even if no records exist. For example, you could add a fallback value like return accList.isEmpty() ? 'No objects found' : result; to avoid the listObjects property staying empty.
内容的提问来源于stack exchange,提问作者molinet

