Use the crate mockall to mock the email service in integration tests
This commit is contained in:
parent
3626f8a11b
commit
8c70f90234
5 changed files with 109 additions and 23 deletions
71
Cargo.lock
generated
71
Cargo.lock
generated
|
|
@ -852,6 +852,12 @@ version = "0.15.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||
|
||||
[[package]]
|
||||
name = "downcast"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1"
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "1.0.10"
|
||||
|
|
@ -1000,6 +1006,12 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fragile"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619"
|
||||
|
||||
[[package]]
|
||||
name = "frontend"
|
||||
version = "0.1.0"
|
||||
|
|
@ -1971,6 +1983,32 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mockall"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"downcast",
|
||||
"fragile",
|
||||
"mockall_derive",
|
||||
"predicates",
|
||||
"predicates-tree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mockall_derive"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.6"
|
||||
|
|
@ -2303,6 +2341,32 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "3.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"predicates-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "predicates-core"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa"
|
||||
|
||||
[[package]]
|
||||
name = "predicates-tree"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c"
|
||||
dependencies = [
|
||||
"predicates-core",
|
||||
"termtree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.4.1"
|
||||
|
|
@ -2464,6 +2528,7 @@ dependencies = [
|
|||
"cookie",
|
||||
"itertools",
|
||||
"lettre",
|
||||
"mockall",
|
||||
"rand 0.9.1",
|
||||
"rand_core 0.9.3",
|
||||
"ron",
|
||||
|
|
@ -3308,6 +3373,12 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termtree"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
|
|
|
|||
|
|
@ -56,3 +56,4 @@ thiserror = "2"
|
|||
axum-test = "17"
|
||||
cookie = "0.18"
|
||||
scraper = "0.23"
|
||||
mockall = "0.13"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use std::error::Error;
|
||||
use std::{error::Error, sync::Arc};
|
||||
|
||||
use axum_test::TestServer;
|
||||
use cookie::Cookie;
|
||||
use mockall::predicate;
|
||||
use scraper::{ElementRef, Html, Selector};
|
||||
|
||||
use recipes::app;
|
||||
use recipes::{app, email};
|
||||
use serde::Serialize;
|
||||
|
||||
mod utils;
|
||||
|
|
@ -104,7 +105,18 @@ pub struct SignUpFormData {
|
|||
#[tokio::test]
|
||||
async fn sign_up() -> Result<(), Box<dyn Error>> {
|
||||
// Arrange.
|
||||
let state = utils::common_state().await?;
|
||||
let mut mock_email_service = utils::mock_email::MockEmailService::new();
|
||||
mock_email_service
|
||||
.expect_send_email()
|
||||
.with(
|
||||
predicate::eq("president@spaceball.planet"),
|
||||
predicate::always(),
|
||||
predicate::always(),
|
||||
)
|
||||
.times(1)
|
||||
.returning(|_email, _title, _message| Ok(()));
|
||||
|
||||
let state = utils::common_state_with_email_service(Arc::new(mock_email_service)).await?;
|
||||
let server = TestServer::new(app::make_service(state))?;
|
||||
|
||||
// Act.
|
||||
|
|
@ -122,7 +134,6 @@ async fn sign_up() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
let document = Html::parse_document(&response.text());
|
||||
assert_eq!(document.errors.len(), 0);
|
||||
dbg!(response);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,20 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use recipes::email;
|
||||
use async_trait::async_trait;
|
||||
use mockall::{mock, predicate::*};
|
||||
|
||||
pub struct MockEmailService;
|
||||
use crate::email;
|
||||
|
||||
impl MockEmailService {
|
||||
pub fn create_service() -> Arc<dyn email::EmailServiceTrait> {
|
||||
Arc::new(Self {})
|
||||
mock! {
|
||||
pub EmailService {}
|
||||
#[async_trait]
|
||||
impl email::EmailServiceTrait for EmailService {
|
||||
async fn send_email(&self, email: &str, title: &str, message: &str)
|
||||
-> Result<(), email::Error>;
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl email::EmailServiceTrait for MockEmailService {
|
||||
async fn send_email(
|
||||
&self,
|
||||
_email: &str,
|
||||
_title: &str,
|
||||
_message: &str,
|
||||
) -> Result<(), email::Error> {
|
||||
Ok(())
|
||||
}
|
||||
// Default email service: will crash if `send_email` method is called.
|
||||
pub fn new_mock_email_service() -> Arc<dyn email::EmailServiceTrait> {
|
||||
Arc::new(MockEmailService::new())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
use std::error::Error;
|
||||
use std::{error::Error, sync::Arc};
|
||||
|
||||
use recipes::{app, config, data::db, log};
|
||||
use recipes::{app, config, data::db, email, log};
|
||||
|
||||
mod mock_email;
|
||||
pub mod mock_email;
|
||||
|
||||
pub async fn common_state() -> Result<app::AppState, Box<dyn Error>> {
|
||||
common_state_with_email_service(mock_email::new_mock_email_service()).await
|
||||
}
|
||||
|
||||
pub async fn common_state_with_email_service(
|
||||
email_service: Arc<dyn email::EmailServiceTrait>,
|
||||
) -> Result<app::AppState, Box<dyn Error>> {
|
||||
let db_connection = db::Connection::new_in_memory().await?;
|
||||
let config = config::Config::default();
|
||||
let log = log::Log::new_no_log();
|
||||
|
|
@ -12,7 +18,7 @@ pub async fn common_state() -> Result<app::AppState, Box<dyn Error>> {
|
|||
config,
|
||||
db_connection,
|
||||
log,
|
||||
email_service: mock_email::MockEmailService::create_service(),
|
||||
email_service,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue