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
|
|
@ -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