You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Salesforce重复机会校验触发器的测试类编写求助

Fixing Your Opportunity Duplicate Prevention Trigger & Test Class

Let’s walk through refining your trigger for better performance and fixing up your test class to cover all critical scenarios.

First: Refine Your Trigger

Your original trigger has a couple of efficiency and logic alignment issues. Here’s an improved version that’s more scalable and matches your requirement to block non-admins from creating duplicate Opportunities (same account + type) within 90 days:

trigger leadDuplicatePreventer on Opportunity (before insert) {
    // Skip validation entirely if current user is a System Administrator
    Profile currentUserProfile = [SELECT Id, Name FROM Profile WHERE Id = :UserInfo.getProfileId() LIMIT 1];
    if (currentUserProfile.Name == 'System Administrator') {
        return;
    }

    // Collect unique Trigger_Help__c values from the new Opportunities being inserted
    Set<String> newTriggerHelpValues = new Set<String>();
    for (Opportunity opp : Trigger.new) {
        if (opp.Trigger_Help__c != null) {
            newTriggerHelpValues.add(opp.Trigger_Help__c);
        }
    }

    // Only query existing Opportunities that match the new values (avoids fetching all 90-day records)
    Set<String> existingDuplicateValues = new Set<String>();
    for (Opportunity existingOpp : [
        SELECT Trigger_Help__c 
        FROM Opportunity 
        WHERE Trigger_Help__c IN :newTriggerHelpValues 
        AND CreatedDate = LAST_N_DAYS:90
    ]) {
        existingDuplicateValues.add(existingOpp.Trigger_Help__c);
    }

    // Block insertion for duplicates
    for (Opportunity opp : Trigger.new) {
        if (existingDuplicateValues.contains(opp.Trigger_Help__c)) {
            opp.addError('An Opportunity of this type already exists on this Account. Please contact a system administrator with questions.');
        }
    }
}

Key Improvements:

  • Skips validation immediately for admins (cleaner logic)
  • Only queries existing Opportunities that match the new records’ Trigger_Help__c values (way more efficient for large orgs)
  • Avoids unnecessary data processing by focusing only on relevant records

Next: Complete Your Test Class

Your current test class is missing critical assertions and doesn’t test the admin user scenario. Here’s a full test class that covers both non-admin (blocked) and admin (allowed) cases:

@isTest
private class TestleadDuplicatePreventer {

    // Test that non-admin users can't create duplicate Opportunities
    @isTest
    static void testNonAdminBlockedFromDuplicate() {
        // Create test Account
        Account testAcct = new Account(Name='Test Account');
        insert testAcct;

        // Create first valid Opportunity
        Opportunity firstOpp = new Opportunity(
            Name = testAcct.Name + ' Initial Opportunity',
            StageName = 'Open Opportunity',
            CloseDate = System.today().addMonths(1),
            Oppty_Type__c = 'UCO Service',
            AccountId = testAcct.Id
        );
        insert firstOpp;

        // Create a non-admin user to test with
        Profile nonAdminProfile = [SELECT Id FROM Profile WHERE Name != 'System Administrator' LIMIT 1];
        User nonAdminUser = new User(
            Alias = 'testnonadmin',
            Email = 'nonadmin@testorg.com',
            EmailEncodingKey = 'UTF-8',
            LastName = 'NonAdmin',
            LanguageLocaleKey = 'en_US',
            LocaleSidKey = 'en_US',
            ProfileId = nonAdminProfile.Id,
            TimeZoneSidKey = 'America/Los_Angeles',
            Username = 'nonadmin@testorg.com'
        );
        insert nonAdminUser;

        // Run the test as the non-admin user
        System.runAs(nonAdminUser) {
            // Attempt to create a duplicate Opportunity
            Opportunity duplicateOpp = new Opportunity(
                Name = 'Duplicate Opportunity',
                StageName = 'Open Opportunity',
                CloseDate = System.today().addMonths(2),
                Oppty_Type__c = 'UCO Service',
                AccountId = testAcct.Id
            );

            // Verify insertion fails with the correct error
            Test.startTest();
            Database.SaveResult saveResult = Database.insert(duplicateOpp, false);
            Test.stopTest();

            System.assert(!saveResult.isSuccess(), 'Non-admin user should be blocked from creating duplicates');
            System.assertEquals(
                'An Opportunity of this type already exists on this Account. Please contact a system administrator with questions.',
                saveResult.getErrors()[0].getMessage(),
                'Error message does not match expected text'
            );
        }
    }

    // Test that admin users CAN create duplicate Opportunities
    @isTest
    static void testAdminAllowedToCreateDuplicate() {
        // Create test Account
        Account adminTestAcct = new Account(Name='Admin Test Account');
        insert adminTestAcct;

        // Create first Opportunity
        Opportunity firstAdminOpp = new Opportunity(
            Name = adminTestAcct.Name + ' Initial Opportunity',
            StageName = 'Open Opportunity',
            CloseDate = System.today().addMonths(1),
            Oppty_Type__c = 'UCO Service',
            AccountId = adminTestAcct.Id
        );
        insert firstAdminOpp;

        // Create an admin user to test with
        Profile adminProfile = [SELECT Id FROM Profile WHERE Name = 'System Administrator' LIMIT 1];
        User adminUser = new User(
            Alias = 'testadmin',
            Email = 'admin@testorg.com',
            EmailEncodingKey = 'UTF-8',
            LastName = 'Admin',
            LanguageLocaleKey = 'en_US',
            LocaleSidKey = 'en_US',
            ProfileId = adminProfile.Id,
            TimeZoneSidKey = 'America/Los_Angeles',
            Username = 'admin@testorg.com'
        );
        insert adminUser;

        // Run the test as the admin user
        System.runAs(adminUser) {
            // Create a duplicate Opportunity
            Opportunity adminDuplicateOpp = new Opportunity(
                Name = 'Admin Duplicate Opportunity',
                StageName = 'Open Opportunity',
                CloseDate = System.today().addMonths(2),
                Oppty_Type__c = 'UCO Service',
                AccountId = adminTestAcct.Id
            );

            // Verify insertion succeeds
            Test.startTest();
            insert adminDuplicateOpp;
            Test.stopTest();

            Opportunity insertedOpp = [SELECT Id FROM Opportunity WHERE Id = :adminDuplicateOpp.Id];
            System.assertNotEquals(null, insertedOpp, 'Admin user should be allowed to create duplicates');
        }
    }
}

Key Test Class Fixes:

  • Uses System.runAs() to simulate both user types
  • Explicitly asserts success/failure outcomes instead of just catching exceptions
  • Validates the exact error message is thrown for non-admins
  • Avoids unnecessary SOQL queries by reusing the already inserted Account ID

内容的提问来源于stack exchange,提问作者KattheSpork

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:07:44