はじめに
Redmine plugin開発で、Projectにのカスタムフィールドを使ったテストコードを書く時に、
自分が設定したはずの値が設定されずにはまりました。
わかってしまえば簡単なことだったのですが、同じところではまらないようまとめておきます。
次のようなProjectに紐づくカスタムフィールドと、その値を使ったテストを書きたいとします。
(必要最小限の項目のみ設定します)
Project
id: n
name: 'テストプロジェクト'
ProjectCustomField
id: m
name: '主管部署'
field_format: 'string'
position: 1
CustomValue
customized_type: 'Project'
customized_id: n # Project.id
custom_field_id: m # ProjectCustomField.id
value 'xx開発部'
テストコード(はまったパターン)
例えば次のようにコードを書くとします。(このテスト自体に意味はありません)
before do
custom_field = ProjectCustomField.create(name: '主管部署', field_format: 'string', position: 1)
project = Project.create(name: 'テストプロジェクト')
CustomValue.create(customized_type: 'Project', customized_id: project.id, custom_field_id: custom_field.id)
end
it '主管部署が設定されていること' do
project = Project.first
primary_section = project.custom_field_values.find {|c| c.custom_field.name == '主管部署'}
expect(primary_section.value).to eq 'xx開発部'
end
このテストを実行すると、primary_section.valueがnilになっていました。
ずいぶん悩まされましたが、次のように変更すると期待通りに動きます。
before do
custom_field = ProjectCustomField.create(name: '主管部署', field_format: 'string', position: 1)
project = Project.create(name: 'テストプロジェクト')
CustomValue.create(customized_type: 'Project', customized_id: project.id, custom_field_id: custom_field.id)
end
:
before do
project = Project.create(name: 'テストプロジェクト')
custom_field = ProjectCustomField.create(name: '主管部署', field_format: 'string', position: 1)
CustomValue.create(customized_type: 'Project', customized_id: project.id, custom_field_id: custom_field.id)
end
:
Redmineでは、新しくProjectを作成するときに、カスタムフィールドが存在すれば、自動的に初期値を設定します。
先ほどうまくいかなかった例では、
1.ProjectCustomFieldを作成
2.Projectを作成 => ここで初期値のCustomValueが作成される
3.CustomValueを作成
という順にしていたため、初期値のCustomValueが取得されていました。
テストコード(うまくいくパターン)
ということで、データ作成の順番を変更します。
1.Projectを作成 => 初期値のCustomValueは作成されない
2.ProjectCustomFieldを作成
3.CustomValueを作成
before do
project = Project.create(name: 'テストプロジェクト')
custom_field = ProjectCustomField.create(name: '主管部署', field_format: 'string', position: 1)
CustomValue.create(customized_type: 'Project', customized_id: project.id, custom_field_id: custom_field.id)
end
it '主管部署が設定されていること' do
project = Project.first
primary_section = project.custom_field_values.find {|c| c.custom_field.name == '主管部署'}
expect(primary_section.value).to eq 'xx開発部'
end
もしくは、自動生成されたCustomValueの値を変更する形が良いかもしれません。