首页 > 解决方案 > Salesforce 测试类获取 System.JSONException:格式错误的 JSON:列表/设置错误开头应为“[”

问题描述

我已经编写了一个触发器和处理程序类(它使用了未来的方法)并且效果很好。我真的很难为它编写测试类。我的第一个问题是代码覆盖率很高(在调整之前它在处理程序类中是 0%)。调整后,我收到以下错误: System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set . 有人可以帮忙吗?这是我的代码:触发器:

trigger AccountTriggerKeepAcctTeam on Account (before update) {
    List<AccountTeamMember> listAcc = [SELECT Id, AccountAccessLevel, AccountId, CaseAccessLevel, UserId, ContactAccessLevel, OpportunityAccessLevel, TeamMemberRole, PhotoUrl, Title FROM AccountTeamMember Where AccountId in : Trigger.new AND TeamMemberRole != 'Account Executive']; 
    for(Account acc: Trigger.new){
        Account oldAccount = Trigger.oldMap.get(acc.Id);
        if(acc.OwnerId != oldAccount.OwnerId){
            system.debug('AccountTeamMember records: '+(JSON.serialize(listAcc))); 
            String str = JSON.serialize(listAcc); 
             //delete team member records if required
            AccountTriggerKeepAcctTeamHandler.retainOldTeamMemberOnOwnerChange(str);   
        }
    }
    
}

处理程序:

public class AccountTriggerKeepAcctTeamHandler {
    @future
    public static void retainOldTeamMemberOnOwnerChange(String str){
        system.debug('Future call '+str); 
        List<AccountTeamMember> newlistAcc = (List<AccountTeamMember>) JSON.deserialize(str,List<AccountTeamMember>.class);
        for(AccountTeamMember objAccTeamMember : newlistAcc){
            objAccTeamMember.Id= null;
        }
        system.debug('Account records to insert'+(JSON.serialize(newlistAcc)));
        Upsert newlistAcc;
     }
}

测试类:

@isTest
public class AccountTriggerKeepAcctTeamTest {
    //@TestSetup
    
    static testMethod void AcctOwnerChange(){
        List<User> userList = TestDataFactory.createUser(true, 2);
        Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator']; 
        User u1 = new User(Alias = 'standt', Email='standarduser@testorg1.com', 
            EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', 
            LocaleSidKey='en_US', ProfileId = p.Id, 
            TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg01.com');
        
        insert u1;

        User u2 = new User(Alias = 'standt', Email='standarduser@testorg2.com', 
            EmailEncodingKey='UTF-8', LastName='Testing2', LanguageLocaleKey='en_US', 
            LocaleSidKey='en_US', ProfileId = p.Id, 
            TimeZoneSidKey='America/Los_Angeles', UserName='standarduser@testorg92.com');
        
        insert u2;

        System.runAs(u1){
            Allowed_Account_Owner_Change__c setting = new Allowed_Account_Owner_Change__c();
            setting.Allowed_to_change_Account_Owner__c = true;
            insert setting;
            fferpcore__ExchangeRateGroup__c exrg = new fferpcore__ExchangeRateGroup__c(CurrencyISOCode = 'USD', fferpcore__DefaultCurrency__c = 'USD - U.S. Dollar', Name = 'FF Shared Test Group', fferpcore__SelectedCurrencies__c = 'USD - U.S. Dollar');
            insert exrg;
            c2g__codaCompany__c company = new c2g__codaCompany__c();
            company.Name = 'ApexTestCompany';
            company.RecordTypeId = Schema.SObjectType.c2g__codaCompany__c.RecordTypeInfosByName.get('SUT').RecordTypeId;
            insert company;
            company.c2g__ExchangeRateGroup__c = exrg.Id;
            update company;

            Account acc = new Account(Name = 'Test Acc2', NumberOfEmployees = 500);//TestDataFactory.createAccountwithCurrencyMaster(true);
            acc.OwnerId = userinfo.getUserId();
            insert acc;
            
            AccountTeamMember accTeam   = new AccountTeamMember();
            accTeam.UserId                  =  acc.OwnerId;
            accTeam.AccountAccessLevel  =  'Read';
            accTeam.AccountId           =  acc.Id;
            insert accTeam;
            
            System.debug('## User '+userinfo.getUserName());
            //create opportunity

            
        //}        

   // }
    
  //  static testMethod void testAcctOwnerChange(){
       // User u = [Select id, LastName from User where LastName = 'Testing2'];
       // Account acc = [Select id, OwnerId from Account Limit 1];
       Test.startTest();
        acc.OwnerId = u2.id;
        update acc;
        AccountTriggerKeepAcctTeamHandler.retainOldTeamMemberOnOwnerChange(JSON.serialize(acc));
        //System.assertEquals(accTeam.UserId,u2.Id);
        Test.stopTest();
        //AccountTeamMember atm = [Select userId,AccountId, AccountAccessLevel from AccountTeamMember where AccountId =: acc.Id];
        
    }
    
    

}

有人可以帮忙吗?我是初学者顶点开发

触发 Alin 测试类的尝试:

trigger AccountTriggerKeepAcctTeam on Account (before update) {
    Set<Id> accteammbrId = new Set<Id>();
    List<AccountTeamMember> listAcc = [SELECT Id, AccountAccessLevel, AccountId, CaseAccessLevel, UserId, ContactAccessLevel, OpportunityAccessLevel, TeamMemberRole, PhotoUrl, Title FROM AccountTeamMember Where AccountId in : Trigger.new AND TeamMemberRole != 'Account Executive']; 
    for(Account acc: Trigger.new){
        Account oldAccount = Trigger.oldMap.get(acc.Id);
        if(acc.OwnerId != oldAccount.OwnerId){
            //system.debug('AccountTeamMember records: '+(JSON.serialize(listAcc))); 
            //String str = JSON.serialize(listAcc); 
            for(AccountTeamMember actmbr : listAcc){
                accteammbrId.add(actmbr.Id);
            }
            
             //delete team member records if required
            AccountTriggerKeepAcctTeamHandler.retainOldTeamMemberOnOwnerChange(accteammbrId);   
        }
    }
    
}

public class AccountTriggerKeepAcctTeamHandler {
    @future
    public static void retainOldTeamMemberOnOwnerChange(Set<Id> AccteambrId){
        List<AccountTeamMember> newlistAcc = [SELECT Id, AccountAccessLevel, AccountId, CaseAccessLevel, UserId, ContactAccessLevel, OpportunityAccessLevel, TeamMemberRole, PhotoUrl, Title FROM AccountTeamMember Where AccountId in :AccteambrId];
        //system.debug('Future call '+str); 
        //List<AccountTeamMember> newlistAcc = (List<AccountTeamMember>) JSON.deserialize(str,List<AccountTeamMember>.class);
        for(AccountTeamMember objAccTeamMember : newlistAcc){
            objAccTeamMember.Id= null;
        }
        //system.debug('Account records to insert'+(JSON.serialize(newlistAcc)));
        system.debug('Account records to insert' + newlistAcc);
        Upsert newlistAcc;
    }
}

标签: apex

解决方案


我不明白为什么你必须首先序列化列表。更改您的 retainOldTeamMemberOnOwnerChange 以接受 List 作为参数并且根本不使用 JSON。然后在您的测试课程中创建一个帐户,为其分配一个帐户团队并更改所有者。之后,您将查询关联的 AccountTeamMember 列表,并在帐户所有权更改之前针对 AccountTeamMember 声明它。如果不够清楚,我可以给你一个代码示例,但我认为这个练习对你有好处。

编辑:我明白了。我的错。这就是我用于测试覆盖率的内容。如果需要,我还可以提供来自触发器的代码示例。

扳机:

trigger AccountTrigger on Account (before update, After Update) {
    if(trigger.isBefore){
        if(trigger.isUpdate){
            AccountTriggerHandler.retainAccountTeam(trigger.new, trigger.oldMap);
        }
    }
}

处理程序:

public class AccountTriggerHandler {
    public static void retainAccountTeam(List<Account> newList, Map<Id, Account> oldMap) {
        Set<Id> accountsWithNewOwners = new Set<Id>();
        for(Account acc : newList){
            if(acc.OwnerId != oldMap.get(acc.Id).OwnerId){
                accountsWithNewOwners.add(acc.Id);
            }
        }
        if(accountsWithNewOwners.size() > 0){
            List<AccountTeamMember> listAcc = [SELECT Id, AccountAccessLevel, AccountId, CaseAccessLevel, UserId, ContactAccessLevel, OpportunityAccessLevel, TeamMemberRole, PhotoUrl, Title FROM AccountTeamMember WHERE AccountId IN :accountsWithNewOwners]; 
            system.debug('AccountTeamMember records: '+(JSON.serialize(listAcc))); 
            String str = JSON.serialize(listAcc); 
            // delete team member records if required
            retainOldTeamMemberOnOwnerChange(str); 
        }
    }

    //Before Update calls the future method that basically reinserts the Account Team member records. You can also consider deleting the Account Team Member records before calling the future method. 
    @future
    public static void retainOldTeamMemberOnOwnerChange(String str){
        system.debug('Future call '+str); 
        List<AccountTeamMember> newlistAcc = (List<AccountTeamMember>) JSON.deserialize(str,List<AccountTeamMember>.class);
        for(AccountTeamMember objAccTeamMember : newlistAcc){
            objAccTeamMember.Id= null;
        }
        system.debug('Account records to insert'+(JSON.serialize(newlistAcc)));
        Upsert newlistAcc;
    }
}

测试方法:

static testMethod void test_retainAccountTeam(){
    Id mhbkRTId = Schema.SObjectType.Account.getRecordTypeInfosByName().get('MHBK').getRecordTypeId();
    Profile p = [SELECT Id FROM Profile WHERE Name='System Administrator']; 
    User u = new User(
        Alias = 'rivacon', 
        Email = 'rivaConnector@testorg.com', 
        EmailEncodingKey = 'UTF-8', 
        LastName = 'Connector', 
        FirstName = 'Riva', 
        LanguageLocaleKey = 'en_US', 
        LocaleSidKey = 'en_US', 
        ProfileId = p.Id, 
        TimeZoneSidKey = 'America/Los_Angeles', 
        UserName = 'rivaConnector@testorg.com');
    insert u;

    User u2 = new User(
        Alias = 'updated', 
        Email = 'rivaConnector@testorg.com', 
        EmailEncodingKey = 'UTF-8', 
        LastName = 'Connector', 
        FirstName = 'Riva2', 
        LanguageLocaleKey = 'en_US', 
        LocaleSidKey = 'en_US', 
        ProfileId = p.Id, 
        TimeZoneSidKey = 'America/Los_Angeles', 
        UserName = 'rivaConnector2@testorg.com');
    insert u2;
    
    system.runAs(u){
        Account acc = new Account(RecordTypeId = mhbkRTId,Name = 'test',Branch__c='London',Industry='Banking',Year_Founded__c='1900',BillingStreet = '1 Long Rd',BillingCity = 'City',CurrencyIsoCode = 'GBP');
        insert acc;
            
        AccountTeamMember atm = new AccountTeamMember();
        atm.AccountId =  acc.Id;
        //atm.Name ='Test ATM';
        atm.TeamMemberRole = 'Sales Assistant';
        atm.UserId = u.Id;
        insert atm;

        Test.startTest();
        acc.OwnerId = u2.Id;
        update acc;
        Test.stopTest();

        System.debug('usr1 ' + u.id);
        System.debug('usr2 ' + u2.id);
        Account updatedAccount = [SELECT OwnerId FROM Account WHERE Id = :acc.Id];
        system.assertEquals(u2.Id, updatedAccount.OwnerId);

        List<AccountTeamMember> teamMembers = [SELECT Id, AccountAccessLevel, AccountId, UserId, TeamMemberRole, Title FROM AccountTeamMember WHERE AccountId = :acc.Id];
        system.assertEquals(1, teamMembers.size());
        system.assertEquals(teamMembers[0].TeamMemberRole, atm.TeamMemberRole);
    }

推荐阅读