在Apex v24.0中对OpportunityLineItem进行单元测试时,如何避免使用STANDARD_PRICE_NOT_DEFINED?

时间:2012-02-06 18:11:29

标签: salesforce apex-code force.com

显然,Salesforce.com中Apex的Spring '12 / v24.0版本的新功能是单元测试不再能够访问“真实”数据 - 因此(如果我正确理解更改) SOQL查询现在只会检索在单元测试过程中插入的对象 - 甚至可能受到一些限制。

无论如何,这似乎将OpportunityLineItem测试抛出窗口,因为:

  • 在没有PriceBookEntryId的情况下插入OpportunityLineItem是不可能的,但是
  • 您不能为产品X插入新的价目表条目,除非您已经有产品X的标准价格手册条目,但是
  • 测试数据中没有标准价格手册,因为与所有表格一样,Pricebook2表在单元测试运行开始时实际上是空的,并且
  • 无法在Apex中创建标准价格手册

我真的希望我至少得到这四点中的一个是错误的,但到目前为止,我现有的单元测试没有任何变化表明它们中的任何一个是错误的。这当然意味着我的单元测试不再有效。这件事发生在一夜之间 - 周五我的沙盒中的测试运行正常,现在他们失败了。

我是否遗漏了某些内容,或者这是新SFDC版本中的错误?

5 个答案:

答案 0 :(得分:14)

夏季14推出了新功能,您现在可以使用Test.getStandardPricebookId()获取标准价格手册ID,而无需将SeeAllData设置为True

答案 1 :(得分:12)

首先,为了让您放心,没有计划弃用seeAllData标志。我们不会从你身下拉出地毯。至于在顶点测试中创建标准价格手册,我不确定。我敢肯定,在今天的平台上,有几个领域没有现有数据的测试很困难,这就是为什么有seeAllData标志的原因之一。我们将在接下来的几个版本中试图缩小这些差距。

答案 2 :(得分:3)

我刚刚碰到了这个,虽然你的帖子已经过时了,但这是谷歌的第一个结果,所以我想我会分享我的所作所为。

我的基本架构是一个测试类,它将实用程序类作为一种动态创建测试数据的方式(还有其他方法,这是我的习惯)。

简短版本:

  • 设置查看所有数据为真
  • 确保标准价格手册有效
  • 为标准价格手册添加价格手册条目 - 标记为有效
  • 为您测试价格手册添加价格手册条目 - 标记为有效

测试类:

@isTest (seeAllData=true)
public with sharing class RMA_SelectLineItemsControllerTest {

    static testmethod void testBasicObjects() {
        Pricebook2 standard = [Select Id, Name, IsActive From Pricebook2 where IsStandard = true LIMIT 1];
        if (!standard.isActive) {
            standard.isActive = true;
            update standard;
        }

        Pricebook2 pb = RMA_TestUtilities.createPricebook();
        Product2 prod = RMA_TestUtilities.createProduct();
        PricebookEntry pbe = RMA_TestUtilities.createPricebookEntry(standard,pb,prod);
    }

}

实用程序方法如下所示(仅显示新PBE周围):

public static PricebookEntry createPricebookEntry (Pricebook2 standard, Pricebook2 newPricebook, Product2 prod) {
    System.debug('***** starting one');
    PricebookEntry one = new PricebookEntry();
    one.pricebook2Id = standard.id;
    one.product2id = prod.id;
    one.unitprice = 1249.0;
    one.isactive = true;
    insert one;
    System.debug('***** one complete, ret next');
    PricebookEntry ret = new PricebookEntry();
    ret.pricebook2Id = newPricebook.id;
    ret.product2id = prod.id;
    ret.unitprice = 1250.0;
    ret.isactive = true;
    insert ret;
    return ret;
}

答案 3 :(得分:1)

另一种解决方法是让你的触发器意识到使用Test.isRunningTest()在测试中运行,但我认为这个解决方案错过了最佳实践的观点,我认为这是将测试分离的重点从预先存在的数据。

如果代码在测试环境中运行,Salesforce可以使Pricebook2.isStandard字段可写,或者特定标准价格手册记录应该与用户和配置文件具有相同的状态

答案 4 :(得分:0)

Please let me know if anyone has used  Test.getStandardPricebookId() and able to insert opportunity line item in test class. I tried this method with below mentioned code but got an error ": STANDARD_PRICE_NOT_DEFINED, No standard price defined for this product: []".

Note: I have seeAllData=false

ID standardPBID = Test.getStandardPricebookId();

            PriceBook2 pb = new PriceBook2();
            pb.name = 'GEW Water CMS';
            pb.isActive=true;
            insert pb;

Product2 prod= new Product2();
                prod.name='TestProd';
                prod.productcode='4568';
                prod.isActive=true;
                insert prod;



PricebookEntry standardPrice = new PricebookEntry(Pricebook2Id = standardPBID, Product2Id = prod.Id, UnitPrice = 10000, IsActive = true,  currencyISOCode='USD' );

                PriceBookEntry pbe= new PricebookEntry(pricebook2id=pb.id, product2id=prod.id,unitprice=2000, isActive=true, currencyISOCode='EUR');
                insert pbe;

                OpportunityLineItem oli = new OpportunityLineItem(OpportunityId = OppList[0].Id, pricebookentryid=pbe.id, UnitPrice = 100, Quantity = 1);
                insert oli;