salesforce開発スクラップ

🔰 Salesforceの基本構成
1. CRMとは?
CRMは「顧客との関係を管理するシステム」。顧客情報、商談、サポート履歴などを一元管理し、営業やマーケティング、カスタマーサービスを強化します。
2. Salesforceの主要な製品
製品 | 主な用途 |
---|---|
Sales Cloud | 営業支援(リード管理、商談管理など) |
Service Cloud | カスタマーサポート(問い合わせ管理など) |
Marketing Cloud | マーケティングの自動化(メール、SNSなど) |
Experience Cloud | 顧客・パートナー向けポータル作成 |
Commerce Cloud | ECサイトの構築・運用 |
Salesforce Platform | カスタムアプリ開発(ノーコード/ローコード対応) |
🧱 基本用語
用語 | 意味 |
---|---|
オブジェクト(Object) | 顧客や商談などのデータの種類(Excelで言う「シート」) |
レコード(Record) | 個々のデータ(Excelで言う「行」) |
項目(Field) | レコードの属性(Excelで言う「列」) |
リード(Lead) | 見込み客の情報 |
商談(Opportunity) | 実際の販売活動 |
取引先(Account) | 顧客会社などの情報 |
取引先責任者(Contact) | 担当者(人)の情報 |
⚙️ 操作の基本フロー(Sales Cloudの例)
- リードを登録(例:展示会で得た名刺情報)
- リードを取引先・商談に変換
- 商談の進捗を管理(フェーズ管理)
- 成約したら「クローズ・ウィン」で終了
🛠 カスタマイズのポイント
- オブジェクト追加:自社業務に合わせたデータ構造を作れる
- ワークフロー/プロセスビルダー/フロー:業務自動化(通知、更新など)
- レポートとダッシュボード:リアルタイムで成果を可視化
- Lightning App Builder:画面レイアウトを自由に設計
☁️ 特徴とメリット
- クラウドベースなのでインストール不要・リモート利用可
- アップデートが自動(年3回)
- ノーコードでも柔軟にカスタマイズ可能
- AppExchangeで拡張アプリを導入可能
開発者公式ブログ

kebab-case
を使う場面【主にHTML側】
1. コンポーネントのタグ名
LWCコンポーネントをHTML上で使うときは、必ず kebab-case で記述します。
<my-custom-component></my-custom-component>
たとえApexクラスやJSファイル名が MyCustomComponent
でも、HTMLでは my-custom-component
と書きます。
2. カスタムデータ属性
data-
属性も kebab-case
になります。
<div data-user-id="12345"></div>
3. CSSクラス名
クラス名も基本的に kebab-case で書くことが多いです(HTML/CSSの一般慣習に従うため)。
<template>
<div class="profile-card-header">Hello</div>
</template>

prettierを適応させるためのコマンド
npm install -g prettier prettier-plugin-apex @prettier/plugin-xml\

文字数は200に設定しておくと見やすい
.prettierrcファイルの中に直接書く
{
"trailingComma": "none",
"plugins": ["prettier-plugin-apex", "@prettier/plugin-xml"],
"overrides": [
{
"files": "**/lwc/**/*.html",
"options": { "parser": "lwc" }
},
{
"files": "*.{cmp,page,component}",
"options": { "parser": "html" }
}
],
"printWidth": 200
}

ログ出力パターン
単一ログ
console.log("変数値", this.variable);
System.debug('変数値: ' + this.variable);
JSONパターン
console.log(JSON.stringify({ 変数値: this.variable }));
System.debug('[DEBUG] variableList: ' + JSON.serialize(variableList));
動いているかどうかの確認
console.log('[LOG] ファイル名 関数名 1');

開発者コンソール検証コード
開発者コンソールで Apex 実行(Execute Anonymous)時に必要なもの
1. 依存クラス・メソッドが存在していること
- 使いたいクラスがすでに本番 or sandbox にデプロイ済みであること。
- そのクラスのメソッドが
public
orglobal
であること - DTO や DAO クラスがすべてコンパイル済み。
2. 検索条件クラスのインスタンスを生成する
-
new クラス名()
で条件用クラスを生成し、必要な値を入れる。
className supplie = new className();
supplie.supplierName = 'テスト株式会社';
3. DAO(ロジック)を呼び出す
- SOQLを生成するメソッドを呼ぶ。
DaoclassName dao = new DaoclassName();
String query = dao.getSalesOrderDetailQuery(supplie, Date.today(), false);
※ Date.today() のように日付をコード内で渡しているのは、SOQL内でバインド変数として利用するためです
4. クエリの実行と結果確認
List<SObject> records = Database.query(query);
System.debug('取得件数: ' + records.size());

Apexの検索条件クラスとはどのようなものか
下記のようなクラスがそれにあたる。
※データ転送オブジェクト(DTO)と混同しないように気を付けること
global class SearchFilterItem {
@AuraEnabled
public String fieldA { get; set; }
@AuraEnabled
public String fieldB { get; set; }
@AuraEnabled
public String fieldC { get; set; }
// コンストラクタはグローバルで初期化値を空文字にする
global SearchFilterItem() {
fieldA = '';
fieldB = '';
fieldC = '';
}
}
下記のコードのメリットは以下の通り。
-
fieldA
/fieldB
、fieldC
など、明確に「検索条件」に該当するフィールドが多数ある - 初期値が用意されており、検索フォームの「絞り込み条件」として使用するのにピッタリな構造
- データの移動ではなく、「どんな条件で検索するか」を保持する用途がメインとして使える

LWCのeventの受け取り方の違い
event.target.value
- HTML標準の
<input>
や<selectなど>
で使用する -
target
はイベントが発生したDOM要素。ネイティブなUIコンポーネントはvalueプロパティを持っているため直接取れる。
event.detail.value
- LWCなどで
CustomEvent
を使って値を渡している場合に使用する -
CustomEvent
はdetail
プロパティに好きなデータを持たせられるので、値はそこに入っている。LWCではこれが推奨されている。

LWCのデコーダー一覧
Salesforce(特にLightning Web Components, LWC)における @api
のような**デコレーター(decorators)**は、クラスのプロパティやメソッドに特別な意味を与えるために使われます。
デコレーター | 用途 |
---|---|
@api |
親コンポーネントと子コンポーネント間でプロパティやメソッドを公開する。主に親から値を受け取る際に使用する |
@track |
リアクティブな内部状態を定義する(現在は非推奨に近く、普通は this.property = ... のように普通のプロパティでもリアクティブに働く)。 |
@wire |
Salesforce のデータ(Apex や LDS)との連携を行う。自動的にデータを取得・更新するために使用。 |
@readonly |
読み取り専用のプロパティを示す(※正式なLWC APIには含まれないが、Auraでは存在していた)。一般的には使わない。 |

Apex のアノテーション一覧
アノテーション | 説明 |
---|---|
@AuraEnabled |
LWCやAuraからApexメソッドやプロパティを使えるようにする。 |
@AuraEnabled(cacheable=true) |
クライアント側でキャッシュ可能なApexメソッドとして公開する(主に @wire 用)。 |
@InvocableMethod |
フローやプロセスビルダーで呼び出せるようにする。 |
@future |
非同期処理を実行する。 |
@isTest |
テストクラス・メソッドを示す。 |
@testSetup |
テストデータセットアップ用のメソッドに使う。 |

LWCの初期化処理について
ライフサイクル名 | いつ呼ばれるか |
---|---|
constructor() | コンポーネントの作成時 |
connectedCallback() | 要素がドキュメントに挿入されるとき |
renderedCallback() | コンポーネントを表示するとき |
disconnectedCallback() | 要素が削除されたとき |
errorCallback() | 下位コンポーネントでエラーが起きたとき |
通常の初期化処理
とりあえずで確認したい場合はここに書いてみる
connectedCallback() {
}

標準コンポーネント(lightning-* コンポーネント)
📋 基本UIコンポーネント
コンポーネント | 説明 |
---|---|
lightning-button |
通常のボタン |
lightning-button-icon |
アイコン付きボタン |
lightning-input |
テキスト/数値/メール等の入力欄 |
lightning-textarea |
複数行入力 |
lightning-checkbox |
チェックボックス |
lightning-radio-group |
ラジオボタン |
lightning-combobox |
ドロップダウン |
lightning-slider |
スライダー入力 |
lightning-toggle |
トグルスイッチ |
🧩 データ表示系
コンポーネント | 説明 |
---|---|
lightning-card |
カード型UI |
lightning-datatable |
テーブル |
lightning-formatted-text |
書式付きテキスト |
lightning-formatted-number |
書式付き数値 |
lightning-badge |
バッジ(ラベル) |
lightning-pill |
タグのような要素 |
lightning-progress-bar |
進捗バー |
lightning-spinner |
読み込み中のスピナー |
📅 日付・時間
コンポーネント | 説明 |
---|---|
lightning-datepicker |
日付入力 |
lightning-timepicker |
時間入力 |
📦 ナビゲーション・レイアウト
コンポーネント | 説明 |
---|---|
lightning-tabset |
タブUI |
lightning-accordion |
アコーディオンUI |
lightning-layout |
レイアウト制御 |
lightning-tree |
ツリー構造 |
lightning-breadcrumb |
パンくずリスト |
🔒 認証・セキュリティ系
コンポーネント | 説明 |
---|---|
lightning-record-edit-form |
標準オブジェクトの編集フォーム |
lightning-record-view-form |
標準オブジェクトの表示フォーム |
lightning-input-field |
record-edit-form 内で使うフィールド |
📁 ファイル関連
コンポーネント | 説明 |
---|---|
lightning-file-upload |
ファイルアップロード |
lightning-avatar |
ユーザーやレコードの画像表示 |
🔧 システム・ユーティリティ
コンポーネント | 説明 |
---|---|
lightning-navigation |
ページ遷移用のユーティリティ |
lightning-toast |
トースト通知(JSで呼び出し) |
lightning-modal |
モーダルウィンドウ(v58以降) |

[NoErrorObjectAvailable] Script error.
親コンポーネント
<template>
<div onchildnotification={ghostMethod}>
<div onchildnotification={handleChildNotification}>
<lightning-textarea value="Parent Component"></lightning-textarea>
<c-child-comp></c-child-comp>
</div>
</div>
</template>
import { LightningElement } from 'lwc';
export default class ParentComp extends LightningElement {
handleChildNotification() {
console.log('Child Event arrived');
}
}
子コンポーネント
<template>
<lightning-button label="Notify Parent Comp" onclick={notifyParent}></lightning-button>
</template>
import { LightningElement } from 'lwc';
export default class ChildComp extends LightningElement {
notifyParent() {
const event = new CustomEvent('childnotification', { bubbles: true });
this.dispatchEvent(event);
}
}
notifyParentメソッドがonclickで呼ばれる
childnotification
イベントを送信するparentComp
問題点
このコードには、親コンポーネントでイベントが正しくハンドリングされていないという問題がある。
具体的には、handleChildNotification
は一番内側の<div>に設定されているけど、その<div>にイベントが届かない可能性が高い。
問題の原因
親テンプレート内のこの部分:
<div onchildnotification={ghostMethod}>
<div onchildnotification={handleChildNotification}>
<lightning-textarea value="Parent Component"></lightning-textarea>
<c-child-comp></c-child-comp>
</div>
</div>
<c-child-comp>
からbubbles: true
でイベントを送信しているが、そのイベントはLWCのシャドウDOMによって制限されるため、親コンポーネントの<div>には伝達しない。
WC では、カスタムイベントがシャドウDOMの外に出ないという制約があるため、bubbles: true
だけでは親コンポーネントのテンプレート上でイベントを捕捉できない。
解決策
composed: true
を設定する
const event = new CustomEvent('childnotification', { bubbles: true, composed: true });
composed: true
を加えることで、シャドウDOM の外にイベントが出るようになる。

ESLintでエラー表示をかき消す
デプロイができていて、プログラム的にも何も問題がないのに、なぜかエラー表示される場合、以下のコメントを記入することによって表示を消すことができる。
/* eslint-disable no-await-in-loop */
/* eslint-enable no-await-in-loop */

nullチェックして代入する書き方
これがnullのときに変数aの値を入れる
const userid = event.target.value;
↓↓こんな感じになる
const userid = event.target.value ?? a;
null
または undefined
のときに判定される
const userid = event.target.value ? event.target.value : a;
空文字・0 を考慮したいときはこんな感じに書く
-
event.target.value
が truthy(真っぽい値) なら → それをuserid
に代入 - そうでなければ(falsy なら) →
a
の値を代入

現在ログインしているユーザー名を取得
Apex側の処理
/**
* 現在ログインしているユーザー名
*/
@AuraEnabled(cacheable=true)
public static User getCurrentUser() {
return [SELECT Id, Name, Email FROM User WHERE Id = :UserInfo.getUserId()];
}
LWC側の処理
import getCurrentUser from "@salesforce/apex/Apexクラス名.getCurrentUser";
@wire(getCurrentUser)
wiredUser({ error, data }) {
if (data) {
this.currentUser = data;
console.log("ユーザー名:", this.currentUser.Name);
} else if (error) {
console.error(error);
}
}

現在ログインしているユーザーIDを取得
Apex側の処理
Id currentUserId = UserInfo.getUserId();
System.debug('ユーザーID: ' + currentUserId);
LWC側の処理
import USER_ID from '@salesforce/user/Id';
console.log('ログインユーザーID:', this.userId);

JavaScriptのスプレット構文の書き方
return { ...existingData, updatedProperty: newValue };
-
...existingData
- existingData というオブジェクトのすべてのプロパティをコピーします。
-
updatedProperty: newValue
- 新たに updatedProperty というプロパティを追加・上書きします。その値は newValue 変数の値です。

親と子の決まり方
Salesforceのコンポーネント構造(特にLightning Web ComponentsやAura Components)における「親コンポーネント」と「子コンポーネント」の関係は、**コンポーネントの入れ子構造(階層構造)**によって決まります。
親コンポーネント・子コンポーネントの決まり方
1. 親コンポーネント
- あるコンポーネントの中で、他のコンポーネントをタグとして呼び出している側が親コンポーネントです。
- 例:
c-child-component
を<c-parent-component>
のテンプレート内で使っている場合、c-parent-component
が親で、c-child-component
が子。
2. 子コンポーネント
- 親コンポーネントのテンプレート内にタグとして埋め込まれているコンポーネント。
- 子は親からプロパティを受け取ったり(@apiで公開されたプロパティ)、イベントを親に発火して通知する役割を持ちます。
具体例(LWCの場合)
親コンポーネント(parentComponent.html)
<template>
<c-child-component message="こんにちは"></c-child-component>
</template>
子コンポーネント(childComponent.js)
import { LightningElement, api } from 'lwc';
export default class ChildComponent extends LightningElement {
@api message; // 親から受け取るプロパティ
}
ポイントまとめ
- 親は子をテンプレート内で呼び出す
- 子は親から@apiで公開された値を受け取る
- 子はイベントを親に送って双方向コミュニケーションができる
- 呼び出し階層で「呼び出す側」が親、「呼ばれる側」が子になる

ページネーションの基本的な考え方
✅ ページネーションとは?
大量のデータを「1ページに◯件だけ」表示し、ページを切り替えながら閲覧できるようにする機能。
用語 | 意味 |
---|---|
pageSize | 1ページあたりに表示するデータ件数(例:10件) |
pageNumber | 現在のページ番号(例:1ページ目 → 1) |
offset | 先頭から何件目から表示するか((pageNumber - 1) * pageSize ) |
totalCount | 該当するデータの総件数(全ページ数を知るために必要) |
totalPages |
Math.ceil(totalCount / pageSize) で求められる、全体のページ数 |
✅ 全体像(構成)
-
データ取得メソッド(Apex)
-
LIMIT
とOFFSET
を使って、指定のページ分だけ取得する。
-
-
総件数取得メソッド(Apex)
-
SELECT COUNT()
で対象データの件数を返す。
-
-
LWCでの状態管理
- 現在のページ番号(
this.currentPage
) - 1ページの表示件数(
this.pageSize
) - 全ページ数(
this.totalPages
)を計算
- 現在のページ番号(
-
ページ移動UI
- 「次へ」「前へ」「1 2 3 ...」などのボタンを用意し、
currentPage
を更新して再取得。
- 「次へ」「前へ」「1 2 3 ...」などのボタンを用意し、
✅ LWC + Apex の場合(サーバーサイド)
public with sharing class AccountPaginationController {
@AuraEnabled(cacheable=true)
public static List<Account> getAccounts(Integer pageSize, Integer pageNumber) {
Integer offsetSize = (pageNumber - 1) * pageSize;
return [
SELECT Id, Name
FROM Account
ORDER BY Name
LIMIT :pageSize OFFSET :offsetSize
];
}
@AuraEnabled(cacheable=true)
public static Integer getTotalCount() {
return [SELECT count() FROM Account];
}
}
import { LightningElement, track } from 'lwc';
import getAccounts from '@salesforce/apex/AccountPaginationController.getAccounts';
import getTotalCount from '@salesforce/apex/AccountPaginationController.getTotalCount';
export default class PaginationSample extends LightningElement {
@track accounts = [];
@track currentPage = 1;
pageSize = 10;
totalRecords = 0;
totalPages = 0;
connectedCallback() {
this.loadData();
}
loadData() {
getTotalCount()
.then(count => {
this.totalRecords = count;
this.totalPages = Math.ceil(count / this.pageSize);
this.fetchAccounts();
});
}
fetchAccounts() {
getAccounts({ pageSize: this.pageSize, pageNumber: this.currentPage })
.then(result => {
this.accounts = result;
});
}
handleNext() {
if (this.currentPage < this.totalPages) {
this.currentPage++;
this.fetchAccounts();
}
}
handlePrev() {
if (this.currentPage > 1) {
this.currentPage--;
this.fetchAccounts();
}
}
}
<template>
<template if:true={accounts}>
<template for:each={accounts} for:item="acc">
<p key={acc.Id}>{acc.Name}</p>
</template>
</template>
<div>
<button onclick={handlePrev} disabled={currentPage <= 1}>Previous</button>
<span>Page {currentPage} of {totalPages}</span>
<button onclick={handleNext} disabled={currentPage >= totalPages}>Next</button>
</div>
</template>

MVC+S+DAOの責務メモ
それぞれの役割
層 | 役割 | 主な処理内容 | SOQL/DMLの位置づけ |
---|---|---|---|
View | UI層 | LWCやAuraなど | なし |
Controller | 入出力処理 | LWCからのリクエストを受けてServiceを呼ぶ | なし |
Service | ビジネスロジック | 処理の流れを記述(条件分岐・ルール判断など) | 原則なし(DAOに委譲) |
DAO | データアクセス専用 | SOQLやDMLを担当、オブジェクト単位でまとめる | ここに集約 |
Model | データの定義 | SObjectやドメインクラス | 定義のみ(SELECTはしない) |
どこに何を書くのが正解なのか
処理内容 | 正しい場所 | 理由 |
---|---|---|
単純なSELECT(1テーブル) | DAO | データアクセスの責任はDAOに一任するため |
複雑なJOIN的処理(2テーブル以上) | Service(がDAOを組み合わせて使う) | ビジネスロジックに近いため |
DML(Insert/Update/Delete) | DAO | 直接DBを操作する責任はDAOに集約 |
条件付き取得(業務判断あり) | Service → DAO | 条件の意味はService層で判断し、取得はDAOに任せる |
まとめ
- DAOがあるなら、SQOL/DMLはDAOに集約するのが正解
- Serviceはあくまで「業務フローの司令塔」
- Controllerはできるだけ「痩せた中継役」して、テストや保守性を高める。

Apex CPU time limit exceeded とは?
検索結果の上限を超えています。検索条件を変更ください。Apex CPU time limit exceededApex CPU time limit exceeded
Apex CPU time limit exceeded とは?
これは Apexコードの実行にかかった時間 が 制限(通常は同期処理で最大10,000ミリ秒 = 10秒)を超えた場合 にスローされるエラーです。
発生するタイミング
このエラーは、Apexコードが処理中にSalesforceのガバナ制限(Governor Limits)に引っかかった場合に、Apexの実行中に出ます。
フェーズ | 発生可能性 | 説明 |
---|---|---|
LWC → Apex 呼び出し時 | ❌ | この時点では出ません。 |
Apex メソッド内部 | ✅ | ここでロジックが複雑・大量データを扱っていると発生します。 |
SOQL ループ・for文などでデータ処理中 | ✅ | ループの中で計算・SOQL・DMLなどが多いとタイムオーバーになります。 |
バッチ処理中 | ✅(別上限) | バッチApexなどでは上限が60秒と緩和されますが、やはり出ます。 |
よくある原因
- 大量のレコードを処理(SOQL結果が多い)
- ネストされたループ(ループ内でループやSOQL)
- 複雑なデータ構造の構築
- TriggerやHelperメソッドが多重に動いている
- 意図しない再帰呼び出し
対処方法の例
- SOQLやDMLをループ外に出す
- ループを減らす、ロジックを単純化
- 処理対象を絞る(検索条件を厳しくする)
- 処理を非同期化する(Queueable, Batch, @futureなど)
- Map, Setを活用して効率化

コンポーネント間通信について
親から子への通信
基本的にはパブリックプロパティで行う
親コンポーネント
<!-- ↓子コンポーネントのパブリックプロパティに値を渡す。 -->
<c-child name-value={name}></c-child>
// JS側で名前を設定
name = 'Taro';
子コンポーネント
<!-- 親から渡された値を使用して、名前を出力。 -->
<div class="sample" style={backgroundStyle}>
<span>Child: {nameValue}</span>
</div>
// @apiをつけることで親コンポーネントからアクセス可能。
import { LightningElement, api } from 'lwc';
export default class Child extends LightningElement {
@api nameValue;
}
子から親への通信
この通信では、カスタムイベントを使用する。
子コンポーネント
<!-- 子要素がクリックされたときに handleClick を実行 -->
<a onclick={handleClick}>
<div class="sample">
<span>{itemLabel}</span>
</div>
</a>
import { LightningElement, api } from 'lwc';
export default class Child extends LightningElement {
@api itemLabel;
handleClick() {
const itemSelectedEvent = new CustomEvent('itemselect', {
detail: this.itemLabel
});
this.dispatchEvent(itemSelectedEvent);
}
}
さらに親の親に伝藩させるには以下のように記述する
const customEvent = new CustomEvent('itemselect', {
detail: this.itemLabel,
bubbles: true, // 親へバブル
composed: true // シャドウDOMを超えて伝播
});
this.dispatchEvent(customEvent);
親コンポーネント
<!-- 子コンポーネントからのイベント「itemselect」をハンドリング -->
<c-child
item-label="Item A"
onitemselect={handleItemSelect}
class="slds-m-horizontal_small">
</c-child>
<c-child
item-label="Item B"
onitemselect={handleItemSelect}
class="slds-m-horizontal_small">
</c-child>
import { LightningElement } from 'lwc';
export default class Parent extends LightningElement {
selectedItem;
handleItemSelect(event) {
this.selectedItem = event.detail;
}
}

“ソーストラッキング ON”によるデプロイエラー
下記のようなエラーが出力される場合
-
VS Code 設定 → 「Salesforce: Enable Source Tracking」を OFF。
※検索窓に salesforce source tracking と入れると見つかります。 -
右クリック → SFDX: Deploy This Source to Org(Push/Pull ではなく Deploy/Retrieve を使う)
エラー原因
- Org 側に Source Tracking が無いのに、VS Code 側は Source Tracking 前提のコマンドを実行
- 拡張機能は内部で push/pull 的な差分検出を挟むことがあり、Org が非対応だと差分=0扱いになり、結果として === Deployed Source\nNo results found が表示されがちです。
- デプロイ対象が 0 件と判断されていた
- 右クリックした場所が packageDirectories 外(sfdx-project.json の "packageDirectories" に含まれない)
- .forceignore によって無視されている
- *-meta.xml だけを選んでいた/メタデータの実体でない
- 未保存(保存しておらず差分が無い)
- manifest(package.xml)が空 or マッチしない
- デフォルト org の取り違え
- 想定と違う org に投げて差分が 0(+その org は非トラッキング)

テストデータが正しく作成されているか確認したい
System.assertNotEquals
の構文:
System.assertNotEquals(expected, actual, [message]);
-
expected
:期待する値 -
actual
:実際の値 -
message
(省略可能):アサートが失敗した場合に表示されるメッセージ
使用例:
1. 値が異なる場合にアサート:
System.assertNotEquals(5, 10, '5 と 10 は異なる');
-
5
と10
が異なるので、アサートが成功します。
null
でないかを確認:
2. 値が System.assertNotEquals(null, 'Some Value', 'null ではない');
-
'Some Value'
はnull
ではないので、アサートが成功します。
3. オブジェクトの比較:
Account acc = new Account(Name = 'Test Account');
insert acc;
System.assertNotEquals(null, acc, 'Accountが正常に作成された');
-
acc
がnull
でないことを確認しています。insert
が成功すれば、acc
はnull
ではないので、アサートが成功します。