Expand description
Test fixtures — Factory and HasFactory.
#[derive(Entity, Default, Clone, Factory)]
struct User { id: u64, email: String, verified_at: Option<DateTime<Utc>> }
let users = User::factory()
.count(3)
.sequence(|user, i| user.email = format!("user{i}@example.com"))
.state(|user| user.verified_at = Some(Utc::now()))
.create(&*users)
.await?;TestApp solved booting an
application. This is the other half: getting rows into it without every
test constructing them field by field, which is why a suite’s setup ends up
longer than its assertions.
§What a factory is for, and what it is not
It builds a row that is valid and uninteresting. Every field a test
does not care about gets a value that will not trip a constraint, and the
one or two fields the test is about are set with state.
That is the whole point: a test that spells out fifteen fields to assert on one of them has buried its subject. A reader cannot tell which value matters, and neither can the next person to change the schema.
§Unique columns need a sequence
A derived factory builds from Default, and three defaults are three
identical rows — which a UNIQUE index refuses on the second. Anything
unique needs sequence, which is handed the index:
.sequence(|user, i| user.email = format!("user{i}@example.com"))Deliberately not automatic. A factory that invented unique values would have to guess which columns are unique and what shape they take, and a guess that is wrong produces a row that fails to insert for a reason nobody can see from the test.
Structs§
- Factory
- Builds models for a test.
Traits§
- HasFactory
- A model with a factory.