yaroslav96
yaroslav96

Reputation: 47

Instancio assign value based on another class field

I'm going to create a lesson model with fields based on course subject:

Lesson:

@Data
public class Lesson {
    private Long id;
    private Course course;
    private String title;
    private String description;
}

Course:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Course {
    private Long code;
    private String subject;
    private String description;
    private Set<User> users;
}

public static final Model<Lesson> LESSON_TEST_MODEL = Instancio.of(Lesson.class)
            .supply(field(Lesson::getId), () -> START_LESSON_ID.getAndSet(START_LESSON_ID.get() + DEFAULT_INCREMENT_STEP))
            .supply(field(Lesson::getCourse), () -> Instancio.of(COURSE_TEST_MODEL).create())
            .assign(given(field(Course::getSubject), field(Lesson::getTitle))
                    .set(When.is("Mathematics"), "Math Lesson")
                    .set(When.is("History"), "History Lesson")
                    .set(When.is("Literature"), "Literature Lesson")
                    .set(When.is("Physics"), "Physics Lesson")
                    .set(When.is("Computer Science"), "Computer Science Lesson"))
            .assign(given(field(Course::getSubject), field(Lesson::getDescription))
                    .set(When.is("Mathematics"), "Lesson on mathematics concepts")
                    .set(When.is("History"), "Lesson on world history")
                    .set(When.is("Literature"), "Lesson on classical literature")
                    .set(When.is("Physics"), "Lesson on fundamental physics")
                    .set(When.is("Computer Science"), "Lesson on computer programming"))
            .toModel();

But providing this line of code causes an exception:

Reason: unresolved assignment expression

The following assignments could not be applied:

 -> from [field(Course, "subject")] to [field(Lesson, "title")]
 -> from [field(Course, "subject")] to [field(Lesson, "description")]

As a result, the following targets could not be assigned a value:

 -> field Lesson.description (depth=1)
 -> field Lesson.title (depth=1)

How the issue could be resolved?

Upvotes: 3

Views: 2193

Answers (1)

armandino
armandino

Reputation: 18562

This error occurs because you are using supply() to set the Lesson.course field:

  .supply(field(Lesson::getCourse), () -> Instancio.of(COURSE_TEST_MODEL).create())

Essentially, you are creating a separate instance of Course and then passing it to supply(). Since the Course was created separately, the second call to Instancio.create() doesn't know what values the course contains. As a result, the assignment is not evaluated and the error is thrown.

This can be fixed by generating the entire Lesson (including Course) within a single Instancio.create() call:

public static final Model<Lesson> LESSON_TEST_MODEL = Instancio.of(Lesson.class)
    .supply(field(Lesson::getId), () -> START_LESSON_ID.getAndSet(START_LESSON_ID.get() + DEFAULT_INCREMENT_STEP))
    // generate Course as part of the Lesson instead of using supply()
    .generate(field(Course::getSubject), gen -> gen.oneOf("Mathematics", "History", "Literature", "Physics", "Computer Science"))
    .assign(given(field(Course::getSubject), field(Lesson::getTitle))
            .set(When.is("Mathematics"), "Math Lesson")
            .set(When.is("History"), "History Lesson")
            .set(When.is("Literature"), "Literature Lesson")
            .set(When.is("Physics"), "Physics Lesson")
            .set(When.is("Computer Science"), "Computer Science Lesson"))
    .assign(given(field(Course::getSubject), field(Lesson::getDescription))
            .set(When.is("Mathematics"), "Lesson on mathematics concepts")
            .set(When.is("History"), "Lesson on world history")
            .set(When.is("Literature"), "Lesson on classical literature")
            .set(When.is("Physics"), "Lesson on fundamental physics")
            .set(When.is("Computer Science"), "Lesson on computer programming"))
    .toModel();

Upvotes: 2

Related Questions