Подтвердить что ты не робот

Как избежать STANDARD_PRICE_NOT_DEFINED при модульном тестировании OpportunityLineItem в Apex v24.0?

По-видимому, новая особенность релиза Apex в Salesforce.com Spring '12/v24.0 заключается в том, что модульные тесты больше не имеют доступа к "реальным" данным - таким образом (если я правильно понимаю изменения ) SOQL-запрос теперь будет извлекать только те объекты, которые были вставлены в течение unit test, и даже с некоторыми ограничениями.

Во всяком случае, это, кажется, бросает OpportunityLineItem, проверяя окно, потому что:

  • Невозможно вставить OpportunityLineItem без PriceBookEntryId, НО
  • Вы не можете вставить новую книгу ценников для продукта X, если у вас уже нет записи стандартной цены для продукта X, НО
  • В тестовых данных нет стандартной книги цены, потому что таблица Pricebook2, как и все таблицы, фактически пуста в начале прогона unit-test, AND
  • В Apex нет возможности создать стандартную книгу цены

Я действительно надеюсь, что у меня есть хотя бы один из этих четырех пунктов, но пока никаких изменений в моих существующих модульных тестах не показалось, что кто-то из них ошибается. Это, конечно, означает, что мои модульные тесты больше не работают. Это произошло буквально в одночасье - тесты прошли отлично в моей песочнице в пятницу, и теперь они терпят неудачу.

Мне что-то не хватает, или это ошибка в новой версии SFDC?

4b9b3361

Ответ 1

Во-первых, чтобы успокоить ум, нет никаких планов, чтобы осудить флаг seeAllData. Мы не собираемся вытаскивать коврик из-под тебя. Что касается создания стандартной ценовой книги в тесте apex, я не уверен. Есть, я уверен, несколько областей, где тестирование без существующих данных сегодня сложно на платформе, что является одной из причин появления флажка seeAllData. Мы попытаемся закрыть эти пробелы в следующих нескольких выпусках.

Ответ 2

В Summer 14 появилась новая функциональность, теперь вы можете использовать Test.getStandardPricebookId() для получения стандартного идентификатора ценники, не устанавливая SeeAllData на True.

Ответ 3

Я просто столкнулся с этим, и хотя ваш пост старый, это первый результат в Google, поэтому я подумал, что поделюсь тем, что сделал.

Моя базовая архитектура - это тестовый класс, который вызывает класс утилиты как способ создания тестовых данных "на лету" (есть другие способы, это моя привычка).

Краткая версия:

  • установить все данные в true
  • убедитесь, что стандартная книга цены активна.
  • добавить запись цены в стандартную книгу цены - флаг как активный
  • добавьте запись в прайс-лист для вас, цена цены - флаг как активный

Класс тестирования:

@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;
}

Ответ 4

Еще одна работа вокруг будет заключаться в том, чтобы ваш триггер был осведомлен о запуске в тесте с использованием Test.isRunningTest(), но я думаю, что это решение не подходит к лучшему методу, который, я считаю, является целым, чтобы сделать тесты изолированными от уже существующих данных.

Возможно, Salesforce может сделать поле Pricebook2.isStandard пригодным для записи, если код работает в контексте теста, или для записи стандартной стандартной книги цены должен быть присвоен тот же статус, что и "Пользователь и профиль"

Ответ 5

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;