Write test

This commit is contained in:
Matt Paul 2020-11-18 17:33:06 +00:00 committed by Ryan Leckey
parent a5cede500e
commit 0b45dd9e3f
3 changed files with 148 additions and 9 deletions

96
Cargo.lock generated
View file

@ -771,6 +771,12 @@ dependencies = [
"zeroize 0.9.3",
]
[[package]]
name = "difference"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
[[package]]
name = "digest"
version = "0.8.1"
@ -801,6 +807,12 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "downcast"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bb454f0228b18c7f4c3b0ebbee346ed9c52e7443b0999cd543ff3571205701d"
[[package]]
name = "either"
version = "1.6.1"
@ -859,6 +871,15 @@ dependencies = [
"instant",
]
[[package]]
name = "float-cmp"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4"
dependencies = [
"num-traits",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -890,6 +911,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fragile"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69a039c3498dc930fe810151a34ba0c1c70b02b8625035592e74432f678591f2"
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
@ -1404,6 +1431,33 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "mockall"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cabea45a7fc0e37093f4f30a5e2b62602253f91791c057d5f0470c63260c3d"
dependencies = [
"cfg-if 0.1.10",
"downcast",
"fragile",
"lazy_static",
"mockall_derive",
"predicates",
"predicates-tree",
]
[[package]]
name = "mockall_derive"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c461918bf7f59eefb1459252756bf2351a995d6bd510d0b2061bd86bcdabfa6"
dependencies = [
"cfg-if 0.1.10",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "native-tls"
version = "0.2.6"
@ -1443,6 +1497,12 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "normalize-line-endings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
[[package]]
name = "num-bigint"
version = "0.2.6"
@ -1791,6 +1851,35 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "predicates"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96bfead12e90dccead362d62bb2c90a5f6fc4584963645bc7f71a735e0b0735a"
dependencies = [
"difference",
"float-cmp",
"normalize-line-endings",
"predicates-core",
"regex",
]
[[package]]
name = "predicates-core"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06075c3a3e92559ff8929e7a280684489ea27fe44805174c3ebd9328dcb37178"
[[package]]
name = "predicates-tree"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e63c4859013b38a76eca2414c64911fba30def9e3202ac461a2d22831220124"
dependencies = [
"predicates-core",
"treeline",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@ -2433,6 +2522,7 @@ dependencies = [
"async-trait",
"dotenv",
"futures",
"mockall",
"paw",
"sqlx",
"structopt",
@ -2885,6 +2975,12 @@ dependencies = [
"serde",
]
[[package]]
name = "treeline"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41"
[[package]]
name = "trybuild"
version = "1.0.35"

View file

@ -13,3 +13,4 @@ sqlx = { path = "../../../", features = ["postgres", "offline", "runtime-async-s
structopt = { version = "0.3", features = ["paw"] }
dotenv = "0.15.0"
async-trait = "0.1.41"
mockall = "0.8.3"

View file

@ -1,7 +1,7 @@
use async_trait::async_trait;
use sqlx::postgres::PgPool;
use sqlx::Done;
use std::{env, sync::Arc};
use std::{env, io::Write, sync::Arc};
use structopt::StructOpt;
#[derive(StructOpt)]
@ -21,27 +21,36 @@ enum Command {
async fn main(args: Args) -> anyhow::Result<()> {
let pool = PgPool::connect(&env::var("DATABASE_URL")?).await?;
let todo_repo = PostgresTodoRepo::new(pool);
let mut writer = std::io::stdout();
handle_command(args, todo_repo).await
handle_command(args, todo_repo, &mut writer).await
}
async fn handle_command(args: Args, todo_repo: impl TodoRepo) -> anyhow::Result<()> {
async fn handle_command(
args: Args,
todo_repo: impl TodoRepo,
writer: &mut impl Write,
) -> anyhow::Result<()> {
match args.cmd {
Some(Command::Add { description }) => {
println!("Adding new todo with description '{}'", &description);
writeln!(
writer,
"Adding new todo with description '{}'",
&description
)?;
let todo_id = todo_repo.add_todo(description).await?;
println!("Added new todo with id {}", todo_id);
writeln!(writer, "Added new todo with id {}", todo_id)?;
}
Some(Command::Done { id }) => {
println!("Marking todo {} as done", id);
writeln!(writer, "Marking todo {} as done", id)?;
if todo_repo.complete_todo(id).await? {
println!("Todo {} is marked as done", id);
writeln!(writer, "Todo {} is marked as done", id)?;
} else {
println!("Invalid id {}", id);
writeln!(writer, "Invalid id {}", id)?;
}
}
None => {
println!("Printing list of all todos");
writeln!(writer, "Printing list of all todos")?;
todo_repo.list_todos().await?;
}
}
@ -49,6 +58,7 @@ async fn handle_command(args: Args, todo_repo: impl TodoRepo) -> anyhow::Result<
Ok(())
}
#[mockall::automock]
#[async_trait]
pub trait TodoRepo {
async fn add_todo(&self, description: String) -> anyhow::Result<i64>;
@ -124,3 +134,35 @@ ORDER BY id
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use mockall::predicate::*;
#[async_std::test]
async fn test_mocked_add() {
let description = String::from("My todo");
let args = Args {
cmd: Some(Command::Add {
description: description.clone(),
}),
};
let mut todo_repo = MockTodoRepo::new();
todo_repo
.expect_add_todo()
.times(1)
.with(eq(description))
.returning(|_| Ok(1));
let mut writer = Vec::new();
handle_command(args, todo_repo, &mut writer).await.unwrap();
assert_eq!(
String::from_utf8_lossy(&writer),
"Adding new todo with description \'My todo\'\nAdded new todo with id 1\n"
);
}
}