So I created my first unit test. It seems like creating testable code needs more functions to work properly. Feels like I'm overengineering using so many small functions. And the test is more work then the function itself.
Anyway I digress. Is this a good unit test? And did I test the correct thing?
Function under test:
/// Takes the Settings values as string slices and returns
/// them as a String with toml formatting
pub fn create_conf_toml(
db_url: &str,
file_path: &str,
jsonrpc_url: &str,
jsonrpc_url_2: &str,
latency_1: &u32,
latency_2: &u32,
scan_api: &str,
mythx_api: &str,
) -> Result<String, Box<dyn std::error::Error>> {
// Create struct and convert to toml string.
let settings_struct = Settings {
storage: Storage {
db_url: db_url.to_string(),
file_path: file_path.to_string(),
},
jsonrpc: JsonRpc {
url_1: jsonrpc_url.to_string(),
url_2: jsonrpc_url_2.to_string(),
latency_1: *latency_1,
latency_2: *latency_2,
},
scan: Scan {
key: scan_api.to_string(),
},
mythx: MythX {
key: mythx_api.to_string(),
},
};
let toml = toml::to_string(&settings_struct).unwrap();
Ok(toml)
}
Test:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_toml_formatting_and_correct_values() {
let toml = create_conf_toml(
"dbtest",
"filetest",
"jsontest1",
"jsontest2",
&40,
&41,
"scantest",
"mythtest",
)
.unwrap();
let test_values = vec![
"[storage]",
"db_url = \"dbtest\"",
"file_path = \"filetest\"",
"",
"[jsonrpc]",
"url_1 = \"jsontest1\"",
"url_2 = \"jsontest2\"",
"latency_1 = 40",
"latency_2 = 41",
"",
"[scan]",
"key = \"scantest\"",
"",
"[mythx]",
"key = \"mythtest\"",
];
let mut test_values_iter = test_values.iter();
let mut toml_iter = toml.lines();
assert!(
test_values_iter.all(|&x| Some(x) == toml_iter.next()),
"One of the lines in the toml string doesn't match the expected output"
);
}
}