テストコードの中で商談レコードを登録する

ちょっと手間取ったのでメモ。

長々と書いてますが、ポイントは
・標準価格表で価格表エントリを登録した後でないと、他の価格表エントリは登録できない
・標準価格表は作れないので、`Test.getStandardPricebookId()`でIDを取得する。
の2点です。

## コードで直接書く
まずは、普通にコードの中だけで作る方法。
価格表は標準価格表をそのまま使ってます。

```java:CreateOpportunityTest.cls
@isTest
public class CreateOpportunityTest{

    @testSetup static void setUpTestData() {
        //insert Product2
        Product2 p2 = new Product2(
            Name = 'MyProduct'
            , IsActive = true
        );
        insert p2;

        //get standard pricebook Id
        Id pb2Id  = Test.getStandardPricebookId();

        //insert PriceBookEntry
        PriceBookEntry pbe = new PriceBookEntry(
            Pricebook2Id = pb2Id
            , Product2Id = p2.Id
            , UnitPrice = 100
            , IsActive = true
        );

        insert pbe;

        //insert Account
        Account a = new Account(
            Name = 'MyCompany'
        );

        insert a;

        //insert Opportunity
        Opportunity o = new Opportunity(
            Name = 'MyOpportunity'
            , AccountId = a.Id
            , StageName = 'Closed Won'
            , CloseDate = System.Today()
        );

        insert o;

        //insert OpportunityLineItem
        OpportunityLineItem oli = new OpportunityLineItem(
            OpportunityId = o.Id
            , PricebookEntryId = pbe.Id
            , Quantity = 5
            , TotalPrice = pbe.UnitPrice * 5
        );

        insert oli;
    }

　　//setupした内容をSELECTしてdebugで出すだけ
    @isTest static void testmethod1(){
        Product2 p2 = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('Product2').getDescribe()));

        system.debug('Product2:' + p2);

        PriceBookEntry pbe = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('PriceBookEntry').getDescribe()));

        system.debug('PriceBookEntry:' + pbe);

        Account a = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('Account').getDescribe()));

        system.debug('Account:' + a);

        Opportunity o = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('Opportunity').getDescribe()));

        system.debug('Opportunity:' + o);

        OpportunityLineItem oli = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('OpportunityLineItem').getDescribe()));

        system.debug('OpportunityLineItem:' + oli);
    }

　　//SELECT * 的な
    private static String cretaQueryAllFields(DescribeSObjectResult sObjResult) {
        String query = 'SELECT';
        Map<String, sObjectField> fields
          = sObjResult.fields.getMap();
        for(sObjectField f : fields.values()) {
            query += ' ' + f.getDescribe().getName() + ',';
        }
        query = query.removeEnd(',');
        query += ' FROM ' + sObjResult.getName();

        return query;
    }
}
```

## CSVから取り込む
次にCSVを使う(Test.loadDataで取り込む)方法です。

標準価格表のIDを事前に把握しておけば、CSVから標準価格を登録することも出来そうなのですが、ベタにIDを埋め込むのはあんまりやりたくないので、標準価格の方はコードで適当な値を設定しておいて、カスタムの価格表をメインに使う方法でやってみます。

```java:CreateOpportunityFromCSVTest.cls
@isTest
private class CreateOpportunityFromCSVTest {

    @testSetup static void setUpTestData() {
        //Insert Product2
        Test.loadData(Product2.sObjectType,'TestProducts');

        //Get standard pricebook Id
        Id pb2Id  = Test.getStandardPricebookId();

        //Insert Custom PriceBook
        Test.loadData(PriceBook2.sObjectType,'TestPriceBooks');

        //Insert Standard PriceBookEntry (中身は適当)
        List<Product2> products = [SELECT Id FROM Product2];
        List<PriceBookEntry> standardPriceBookEntry = new List<PriceBookEntry>();
        for(Product2 p : [SELECT Id FROM Product2]) {
            standardPriceBookEntry.add(new PriceBookEntry(
                Pricebook2Id = pb2Id
                , Product2Id = p.Id
                , UnitPrice = 0
                , IsActive = true
            ));
        }
        insert standardPriceBookEntry;

        //Insert Custom PriceBookEntry
        Test.loadData(PriceBookEntry.sObjectType,'TestPriceBookEntries');

        //Insert Account
        Test.loadData(Account.sObjectType,'TestAccounts');

        //Insert Opporunity
        Test.loadData(Opportunity.sObjectType,'TestOpportunities');

        //Insert OpportunityLineItem
        Test.loadData(OpportunityLineItem.sObjectType,'TestOpportunityLineitems');
    }

    @isTest static void testmethod1(){
        List<Product2> p2 = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('Product2').getDescribe()));

        system.debug('Product2:' + p2);


        List<PriceBook2> pb2 = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('PriceBook2').getDescribe()));

        system.debug('PriceBook2:' + pb2);


        List<PriceBookEntry> pbe = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('PriceBookEntry').getDescribe()));

        system.debug('PriceBookEntry:' + pbe);

        List<Account> a = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('Account').getDescribe()));

        system.debug('Account:' + a);

        List<Opportunity> o = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('Opportunity').getDescribe()));

        system.debug('Opportunity:' + o);

        List<OpportunityLineItem> oli = Database.query(cretaQueryAllFields(
            Schema.getGlobalDescribe().get('OpportunityLineItem').getDescribe()));

        system.debug('OpportunityLineItem:' + oli);
    }

    private static String cretaQueryAllFields(DescribeSObjectResult sObjResult) {
        String query = 'SELECT';
        Map<String, sObjectField> fields
          = sObjResult.fields.getMap();
        for(sObjectField f : fields.values()) {
            query += ' ' + f.getDescribe().getName() + ',';
        }
        query = query.removeEnd(',');
        query += ' FROM ' + sObjResult.getName();

        return query;
    }
}
```

各CSVファイルは以下のような感じ


TestAccounts.csv
-

| ID | Name |
|:-:|:-:|
| ACC0001 | MyCompany1 |
| ACC0002 | MyCompany2 |
| ACC0003 | MyCompany3 |
| ACC0004 | MyCompany4 |
| ACC0005 | MyCompany5 |

TestProducts.csv
-

| ID | Name | IsActive |
|:-:|:-:|:-:|
| PRD0001 | Myproduct1 | TRUE |
| PRD0002 | Myproduct2 | TRUE |
| PRD0003 | Myproduct3 | TRUE |
| PRD0004 | Myproduct4 | TRUE |
| PRD0005 | Myproduct5 | TRUE |

TestPriceBook.csv
-

| ID | Name | IsActive |
|:-:|:-:|:-:|
| BRB0001 | MyPriceBook1 | TRUE |

TestPriceBookEntries.csv
-

| ID | Pricebook2Id | Product2Id | UnitPrice | IsActive | UseStandardPrice |
|:-:|:-:|:-:|:-:|:-:|:-:|
| PBE0001 | BRB0001 | PRD0001 | 50 | TRUE | FALSE |
| PBE0002 | BRB0001 | PRD0002 | 100 | TRUE | FALSE |
| PBE0003 | BRB0001 | PRD0003 | 150 | TRUE | FALSE |
| PBE0004 | BRB0001 | PRD0004 | 200 | TRUE | FALSE |
| PBE0005 | BRB0001 | PRD0005 | 250 | TRUE | FALSE |

TestOpportunities.csv
-

| ID | Name | AccountId | StageName | CloseDate |
|:-:|:-:|:-:|:-:|:-:|
| OPP0001 | Opportunity1 | ACC0001 | Closed Won | 2017-01-01 |
| OPP0002 | Opportunity2 | ACC0002 | Closed Won | 2017-02-01 |
| OPP0003 | Opportunity3 | ACC0003 | Closed Won | 2017-03-01 |
| OPP0004 | Opportunity4 | ACC0004 | Closed Won | 2017-04-01 |
| OPP0005 | Opportunity5 | ACC0005 | Closed Won | 2017-05-01 |

TestOpportunitieLines.csv
-

| OpportunityId | PricebookEntryId | Quantity | UnitPrice |
|:-:|:-:|:-:|:-:|
| OPP0001 | PBE0001 | 5 | 50 |
| OPP0001 | PBE0002 | 4 | 100 |
| OPP0001 | PBE0003 | 3 | 150 |
| OPP0001 | PBE0004 | 2 | 200 |
| OPP0001 | PBE0005 | 1 | 250 |
| OPP0002 | PBE0001 | 5 | 50 |
| OPP0002 | PBE0002 | 4 | 100 |
| OPP0002 | PBE0003 | 3 | 150 |
| OPP0002 | PBE0004 | 2 | 200 |
| OPP0002 | PBE0005 | 1 | 250 |
| OPP0003 | PBE0001 | 5 | 50 |
| OPP0003 | PBE0002 | 4 | 100 |
| OPP0003 | PBE0003 | 3 | 150 |
| OPP0003 | PBE0004 | 2 | 200 |
| OPP0003 | PBE0005 | 1 | 250 |
| OPP0004 | PBE0001 | 5 | 50 |
| OPP0004 | PBE0002 | 4 | 100 |
| OPP0004 | PBE0003 | 3 | 150 |
| OPP0004 | PBE0004 | 2 | 200 |
| OPP0004 | PBE0005 | 1 | 250 |
| OPP0005 | PBE0001 | 5 | 50 |
| OPP0005 | PBE0002 | 4 | 100 |
| OPP0005 | PBE0003 | 3 | 150 |
| OPP0005 | PBE0004 | 2 | 200 |
| OPP0005 | PBE0005 | 1 | 250 |