How to Identify Variables to Create in a Test

How to Identify Variables to Create in a Test

3 Simple Steps:

Step 1: Read the Action/Class You Want to Test

Look at the code of the action or class. For example:

executed do |context|
  student_assessment = context.student_assessment  # ← You need this variable
  enrolment = student_assessment.enrolment         # ← Comes from student_assessment

  if student_assessment.completed?
    # ...
  elsif student_assessment.in_progress? || student_assessment.awaiting_completion?
    # ...

Step 2: Follow the Relationships

student_assessment requires:

enrolment requires:

Check the factories to see these relationships.

Step 3: Build Relationships from the Outside In

Example:

let(:user) { create(:student) }                    # 1️⃣ Start here
let(:klass) { create(:klass) }                     # 2️⃣ Create klass
let(:enrolment) { create(:enrolment, klass:, user:) }  # 3️⃣ Link user + klass
let(:content) { create(:content_assessment) }      # 4️⃣ Create content
let(:student_assessment) {                         # 5️⃣ The main object to test
  create(:student_assessment, user:, enrolment:, content:, status:)
}
let(:status) { :to_be_marked }                     # 6️⃣ State for testing
let(:context) { LightService::Context.make(student_assessment:) }  # 7️⃣ Wrap in context

1. Always check factories first:

grep -r "factory :" spec/factories/ | grep <model_name>
  1. Check model relationships:
grep -r "has_many\|belongs_to\|has_one" app/models/<model_name>.rb

3. Use create (saves to DB) or build (in memory only):

create(:user) - when you need real data

build(:user) - when you only need the object

4. Look at other specs in the same folder for patterns:

ls -la spec/actions/student_tasks/