feat(net): don't use panic to signal test should fail
This commit is contained in:
parent
b6a236ab74
commit
8534eca219
2 changed files with 80 additions and 21 deletions
|
@ -611,36 +611,95 @@ impl From<MockNet> for Net {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for MockNet {
|
impl Drop for MockNet {
|
||||||
|
#[cfg_attr(test, mutants::skip)]
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let unused = self.plans.take();
|
// Don't assert during panic to avoid double panic
|
||||||
if unused.is_empty() {
|
if std::thread::panicking() {
|
||||||
tracing::trace!("no unused expected requests");
|
return;
|
||||||
return; // all good
|
}
|
||||||
|
let unused = self.plans.take();
|
||||||
|
if !unused.is_empty() {
|
||||||
|
log_unused_plans(&unused);
|
||||||
|
assert!(
|
||||||
|
unused.is_empty(),
|
||||||
|
"{} expected requests were not made",
|
||||||
|
unused.len()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
panic_with_unused_plans(unused);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Drop for Net {
|
impl Drop for Net {
|
||||||
|
#[cfg_attr(test, mutants::skip)]
|
||||||
#[tracing::instrument]
|
#[tracing::instrument]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
// Don't assert during panic to avoid double panic
|
||||||
|
if std::thread::panicking() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if let Some(plans) = &self.plans {
|
if let Some(plans) = &self.plans {
|
||||||
let unused = plans.try_lock().expect("lock plans").take();
|
let unused = plans.try_lock().expect("lock plans").take();
|
||||||
if unused.is_empty() {
|
if !unused.is_empty() {
|
||||||
tracing::trace!("no unused expected requests");
|
log_unused_plans(&unused);
|
||||||
return; // all good
|
assert!(
|
||||||
|
unused.is_empty(),
|
||||||
|
"{} expected requests were not made",
|
||||||
|
unused.len()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
panic_with_unused_plans(unused);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn panic_with_unused_plans(unused: Vec<Plan>) {
|
#[cfg_attr(test, mutants::skip)]
|
||||||
eprintln!("These requests were expected, but not made:");
|
fn log_unused_plans(unused: &[Plan]) {
|
||||||
for plan in unused {
|
if !unused.is_empty() {
|
||||||
eprintln!("- {plan}");
|
eprintln!(
|
||||||
|
"Net::drop(): {} expected requests were not made:\n{}",
|
||||||
|
unused.len(),
|
||||||
|
unused
|
||||||
|
.iter()
|
||||||
|
.map(|p| format!(" - {}", p))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Net {
|
||||||
|
/// Assert that all expected requests were made.
|
||||||
|
/// This will fail the test if there are any unused plans.
|
||||||
|
#[cfg_attr(test, mutants::skip)]
|
||||||
|
pub fn assert_no_unused_plans(&self) {
|
||||||
|
if let Some(plans) = &self.plans {
|
||||||
|
let unused = plans.try_lock().expect("lock plans").take();
|
||||||
|
if !unused.is_empty() {
|
||||||
|
log_unused_plans(&unused);
|
||||||
|
assert!(
|
||||||
|
unused.is_empty(),
|
||||||
|
"{} expected requests were not made",
|
||||||
|
unused.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MockNet {
|
||||||
|
/// Assert that all expected requests were made.
|
||||||
|
/// This will fail the test if there are any unused plans.
|
||||||
|
#[cfg_attr(test, mutants::skip)]
|
||||||
|
pub fn assert_no_unused_plans(&self) {
|
||||||
|
let unused = self.plans.take();
|
||||||
|
if !unused.is_empty() {
|
||||||
|
log_unused_plans(&unused);
|
||||||
|
assert!(
|
||||||
|
unused.is_empty(),
|
||||||
|
"{} expected requests were not made",
|
||||||
|
unused.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
panic!("There were expected requests that were not made.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
|
14
tests/net.rs
14
tests/net.rs
|
@ -335,7 +335,7 @@ async fn test_post_by_header_wrong_value() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[should_panic]
|
#[should_panic(expected = "1 expected requests were not made")]
|
||||||
async fn test_unused_post_as_net() {
|
async fn test_unused_post_as_net() {
|
||||||
//given
|
//given
|
||||||
let mock_net = kxio::net::mock();
|
let mock_net = kxio::net::mock();
|
||||||
|
@ -349,18 +349,18 @@ async fn test_unused_post_as_net() {
|
||||||
.body("Post OK")
|
.body("Post OK")
|
||||||
.expect("mock");
|
.expect("mock");
|
||||||
|
|
||||||
let _net = Net::from(mock_net);
|
let net = Net::from(mock_net);
|
||||||
|
|
||||||
//when
|
//when
|
||||||
// don't send the planned request
|
// don't send the planned request
|
||||||
// let _response = Net::from(net).send(client.post(url)).await.expect("send");
|
// let _response = net.send(client.post(url)).await.expect("send");
|
||||||
|
|
||||||
//then
|
//then
|
||||||
// Drop implementation for net should panic
|
net.assert_no_unused_plans();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[should_panic]
|
#[should_panic(expected = "1 expected requests were not made")]
|
||||||
async fn test_unused_post_as_mocknet() {
|
async fn test_unused_post_as_mocknet() {
|
||||||
//given
|
//given
|
||||||
let mock_net = kxio::net::mock();
|
let mock_net = kxio::net::mock();
|
||||||
|
@ -376,10 +376,10 @@ async fn test_unused_post_as_mocknet() {
|
||||||
|
|
||||||
//when
|
//when
|
||||||
// don't send the planned request
|
// don't send the planned request
|
||||||
// let _response = Net::from(net).send(client.post(url)).await.expect("send");
|
// let _response = mock_net.send(client.post(url)).await.expect("send");
|
||||||
|
|
||||||
//then
|
//then
|
||||||
// Drop implementation for mock_net should panic
|
mock_net.assert_no_unused_plans();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
Loading…
Reference in a new issue