-
I have a handler function in Actix web. This function looks like this: pub async fn sample_handler(pool: actix_web::web::Data<sqlx::postgres::PgPool>) -> actix_web::HttpResponse {
...
crate::utils::send_multipart_email(...)
...
}
pub async fn send_multipart_email(...) -> Result<(), String> {
tokio::spawn(send_email(...));
Ok(())
} Then, pub async fn send_email(...) -> Result<(), String> {
let email = lettre::Message::builder()
.from(
format!(
"{} <{}>",
"Some title",
if sender_email.is_some() {
sender_email.unwrap()
} else {
settings.email.host_user.clone()
}
)
.parse()
.unwrap(),
)
.to(format!(
"{} <{}>",
[recipient_first_name, recipient_last_name].join(" "),
recipient_email
)
.parse()
.unwrap())
.subject(subject)
.multipart(
lettre::message::MultiPart::alternative()
.singlepart(
lettre::message::SinglePart::builder()
.header(lettre::message::header::ContentType::TEXT_PLAIN)
.body(text_content.into()),
)
.singlepart(
lettre::message::SinglePart::builder()
.header(lettre::message::header::ContentType::TEXT_HTML)
.body(html_content.into()),
),
)
.unwrap();
let creds = lettre::transport::smtp::authentication::Credentials::new(
settings.email.host_user,
settings.email.host_user_password,
);
// Open a remote connection to gmail
let mailer: lettre::AsyncSmtpTransport<lettre::Tokio1Executor> =
lettre::AsyncSmtpTransport::<lettre::Tokio1Executor>::relay(&settings.email.host)
.unwrap()
.credentials(creds)
.build();
// Send the email
match mailer.send(email).await {
Ok(_) => {
Ok(())
}
Err(e) => {
Err(format!("Could not send email: {:#?}", e))
}
}
} While doing integration testing in Python and using the mock library, I could do something like this: with patch('path/to/where/send_email/was/used'):
response = requests... How can I do something equivalent with Mockall? I need to mock the |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
You can certainly mock send_email. But unlike in Python, you can't select between the real implementation and the mock implementation at runtime. You must do it at compile time. You can do it by creating a module for your mock functions: #[automock]
mod mymod {
pub async fn send_email(...) {unimplemented!()}
} and then in whatever file send_multipart_email is defined, you can select at compile time whether to use the mock: #[cfg(test)]
use crate::mock_mymod::send_email;
#[cfg(not(test)]
use some_other_module::send_email; that's basically what |
Beta Was this translation helpful? Give feedback.
You can certainly mock send_email. But unlike in Python, you can't select between the real implementation and the mock implementation at runtime. You must do it at compile time. You can do it by creating a module for your mock functions:
and then in whatever file send_multipart_email is defined, you can select at compile time whether to use the mock:
that's basically what
#[double]
does, except it makes stronger assumptions about the module naming convention.