在Salesforce Apex中使用静态变量

时间:2016-02-15 10:56:16

标签: variables static salesforce apex

我们在测试类中注意到一些有趣的行为,当使用静态变量来确保触发器只触发一次。考虑以下触发器,类和测试类:

触发:

trigger RecursiveTrigger on Account (before insert) {

    if(RecursiveClass.RunOnce) {
        RecursiveClass.RunOnce = false;
        if(Trigger.isInsert) {
            RecursiveClass.doStuffOnInsert();
        }
        if(Trigger.isUpdate) {
            RecursiveClass.doStuffOnUpdate();
        }        
    }    
}

类别:

public class RecursiveClass {
    public static boolean RunOnce = true;

    public static void doStuffOnInsert() {}
    public static void doStuffOnUpdate() {}
}

识别TestClass:

@IsTest(SeeAllData=false)
public class TestRecursiveClass {

    static testMethod void testAccountInsertUpdate() {
        Account a = new Account(Name = 'Testing Recursive');
        insert a;
        a.Name = 'Testing Update';
        update a;
    }
}

基于此,我希望100%的代码覆盖率,但当你运行它时,行RecursiveClass.doStuffOnUpdate();在触发器中将不会执行,因为静态变量似乎仍然设置。根据我在文档中读到的内容,静态变量仅在整个事务中保存(即插入或更新)。测试类中的更新不是一个全新的事务,还是我误解了这个?

我能解决这个问题的唯一方法是将静态变量分为一个用于插入,一个用于更新。

2 个答案:

答案 0 :(得分:3)

这是因为两个DML语句insert  update是同一个Apex交易的一部分,以下摘录解释得很清楚。

  

静态变量仅在Apex事务的范围内是静态的。它在整个服务器或整个组织中都不是静态的。静态变量的值在单个事务的上下文中保留,并在事务边界之间重置。例如,如果Apex DML请求导致触发器多次触发,则静态变量会在这些触发器调用中持续存在。

您可以找到有关它的详细示例here

修改

还有一件事,您需要更新触发器以处理update以及

trigger RecursiveTrigger on Account(before insert, before update) {
}

修改

而且,以下是如何达到100%覆盖率

@IsTest(SeeAllData=false)
public class TestRecursiveClass {

    static testMethod void testAccountInsertUpdate() {
        Account a = new Account(Name = 'Testing Recursive');
        insert a;
        RecursiveClass.RunOnce = true;
        a.Name = 'Testing Update';
        update a;
   }
}

希望这有帮助。

答案 1 :(得分:2)

您的测试应该是

@IsTest(SeeAllData=false)
public class TestRecursiveClass {

static testMethod void testAccountInsertUpdate() {
    Account a = new Account(Name = 'Testing Recursive');
    insert a;
    a.Name = 'Testing Update';
    RecursiveClass.RunOnce = true;
    update a;
}
}

在下一个DML之前将静态变量设置为true可让您了解用户的下一步操作。静态变量用于防止触发循环。就像,你更新了一个对象,然后在触发器中你做了一些操作,然后更新了这个对象。这可能导致无限循环的触发更新。为了防止使用这个静态变量。