default_test/lib.rs
1//! Provides a Rust trait similar to [Default](https://doc.rust-lang.org/std/default/trait.Default.html) that can be used in tests.
2//!
3//! Often tests need to construct mock instances of structs. For example:
4//! ```rust
5//! struct User {
6//! id: usize,
7//! name: String,
8//! email: String,
9//! admin: bool
10//! }
11//! ```
12//!
13//! While it's tempting to define Default, often tests need mock values for types that
14//! shouldn't apply in production code. Sometimes, tests need values for types that don't even implement Default.
15//!
16//! This crate provides [DefaultTest](./trait.DefaultTest.html), a trait which can provide default instances with mock values.
17//! Tests can construct instances, and use the spread operator to override values.
18//! ```rust
19//! # struct User {
20//! # id: usize,
21//! # name: String,
22//! # email: String,
23//! # admin: bool
24//! # }
25//! use default_test::DefaultTest;
26//!
27//! impl DefaultTest for User {
28//! fn default_test() -> Self {
29//! User {
30//! id: 0,
31//! name: "name".into(),
32//! email: "email".into(),
33//! admin: false
34//! }
35//! }
36//! }
37//!
38//! #[cfg(test)]
39//! mod tests {
40//! #[test]
41//! fn test() {
42//! let user = User {
43//! id: 99
44//! ..User::test_default()
45//! };
46//! // ...
47//! }
48//! }
49//! ```
50//!
51//! This style makes tests much more stable, and when adding a field to a struct, it reduces the amount of required edits in your unit tests.
52//!
53//! ## Roadmap:
54//! - Derive macro which fills sensible defaults that would be useful in unit test implementations.
55//! String files would be filled with their property name, and other types may use T::default() or unique values.
56
57/// A trait for giving a type a useful default value, in the scope of unit tests.
58///
59/// Sometimes, unit tests need to construct a mock value when working with structs, such as:
60/// ```rust
61/// struct User {
62/// id: usize,
63/// name: String,
64/// email: String,
65/// admin: bool
66/// }
67/// ```
68///
69/// DefaultTest can be used to define default mocked values for use in tests.
70/// Tests can construct instances, and use the spread operator to override values.
71/// ```rust
72/// # struct User {
73/// # id: usize,
74/// # name: String,
75/// # email: String,
76/// # admin: bool
77/// # }
78/// use default_test::DefaultTest;
79///
80/// impl DefaultTest for User {
81/// fn default_test() -> Self {
82/// User {
83/// id: 0,
84/// name: "name".into(),
85/// email: "email".into(),
86/// admin: false
87/// }
88/// }
89/// }
90///
91/// #[cfg(test)]
92/// mod tests {
93/// #[test]
94/// fn test() {
95/// let user = User {
96/// id: 99
97/// ..User::test_default()
98/// };
99/// // ...
100/// }
101/// }
102/// ```
103pub trait DefaultTest {
104 /// Returns a "default value" for a type, containing mocked values suitable for use in tests.
105 /// Default values may contain literals, unique numbers, etc, to make test assertions easier to work with.
106 /// # Examples
107 /// ```
108 /// use default_test::DefaultTest;
109 /// let x: String = DefaultTest::default_test();
110 /// ```
111 /// Make your own:
112 /// ```
113 /// use default_test::DefaultTest;
114 ///
115 /// struct Foo {
116 /// bar: String
117 /// }
118 ///
119 /// impl DefaultTest for Foo {
120 /// fn default_test() -> Self {
121 /// Self {
122 /// bar: "bar".into()
123 /// }
124 /// }
125 /// }
126 fn default_test() -> Self;
127}
128
129impl DefaultTest for bool {
130 fn default_test() -> Self {
131 false
132 }
133}
134
135impl DefaultTest for char {
136 fn default_test() -> Self {
137 '-'
138 }
139}
140
141impl DefaultTest for &str {
142 fn default_test() -> Self {
143 "string"
144 }
145}
146
147impl DefaultTest for String {
148 fn default_test() -> Self {
149 "string".into()
150 }
151}
152
153impl DefaultTest for usize {
154 fn default_test() -> Self {
155 0
156 }
157}
158
159impl DefaultTest for isize {
160 fn default_test() -> Self {
161 0
162 }
163}
164
165impl DefaultTest for u8 {
166 fn default_test() -> Self {
167 0
168 }
169}
170
171impl DefaultTest for i8 {
172 fn default_test() -> Self {
173 0
174 }
175}
176
177impl DefaultTest for u16 {
178 fn default_test() -> Self {
179 0
180 }
181}
182
183impl DefaultTest for i16 {
184 fn default_test() -> Self {
185 0
186 }
187}
188
189impl DefaultTest for u32 {
190 fn default_test() -> Self {
191 0
192 }
193}
194
195impl DefaultTest for i32 {
196 fn default_test() -> Self {
197 0
198 }
199}
200
201impl DefaultTest for u64 {
202 fn default_test() -> Self {
203 0
204 }
205}
206
207impl DefaultTest for i64 {
208 fn default_test() -> Self {
209 0
210 }
211}
212
213impl DefaultTest for u128 {
214 fn default_test() -> Self {
215 0
216 }
217}
218
219impl DefaultTest for i128 {
220 fn default_test() -> Self {
221 0
222 }
223}
224
225impl DefaultTest for f32 {
226 fn default_test() -> Self {
227 0.0
228 }
229}
230
231impl DefaultTest for f64 {
232 fn default_test() -> Self {
233 0.0
234 }
235}
236
237// impl<T, E> DefaultTest for Result<T, E>
238// where
239// T: DefaultTest,
240// {
241// fn default_test() -> Self {
242// Ok(T::default_test())
243// }
244// }
245
246// impl<T> DefaultTest for Option<T>
247// where
248// T: DefaultTest,
249// {
250// fn default_test() -> Self {
251// Some(T::default_test())
252// }
253// }