feat(net): don't use panic to signal test should fail
Some checks failed
Test / build (map[name:nightly]) (push) Failing after 34s
Test / build (map[name:stable]) (push) Failing after 24s

This commit is contained in:
Paul Campbell 2024-12-07 20:37:05 +00:00
parent b6a236ab74
commit 4ff267b7ce
2 changed files with 67 additions and 21 deletions

View file

@ -613,34 +613,80 @@ impl From<MockNet> for Net {
impl Drop for MockNet { impl Drop for MockNet {
#[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 {
#[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>) { fn log_unused_plans(unused: &[Plan]) {
eprintln!("These requests were expected, but not made:"); if !unused.is_empty() {
for plan in unused { eprintln!(
eprintln!("- {plan}"); "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.
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.
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)]

View file

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