diff --git a/src/component.rs b/src/component.rs
index 02f40d8..3262387 100644
--- a/src/component.rs
+++ b/src/component.rs
@@ -12,6 +12,7 @@ use std::marker::Send;
 use std::ops::{Deref, DerefMut};
 use std::pin::Pin;
 use std::task::Context;
+use std::thread;
 
 use async_trait::async_trait;
 use futures::{task::Poll, Stream};
@@ -162,7 +163,6 @@ impl From<Message> for TestElement {
 #[derive(Debug)]
 pub struct TestComponent {
     in_buffer: VecDeque<TestElement>,
-    out_buffer: VecDeque<TestElement>,
     expect_buffer: VecDeque<Expect>,
 }
 
@@ -175,7 +175,6 @@ impl TestComponent {
                     .map(|el| TestElement(el))
                     .collect::<Vec<_>>(),
             ),
-            out_buffer: VecDeque::new(),
             expect_buffer: VecDeque::new(),
         }
     }
@@ -212,33 +211,39 @@ impl TestComponent {
             .push_back(Expect::Presence(Box::new(callback), desc.into()))
     }
 
-    /// Asserts expected output and actual output are the same
-    pub fn assert(&mut self) {
-        loop {
-            let out = self.out_buffer.pop_front();
-            let expected = self.expect_buffer.pop_front();
-
-            match (out, expected) {
-                (None, None) => break,
-                (Some(out), Some(expected)) => match expected {
-                    Expect::Element(el) => assert_eq!(String::from(&el), String::from(&out)),
-                    Expect::Iq(cb, _) => cb(Iq::try_from(out.0).unwrap()),
-                    Expect::Message(cb, _) => cb(Message::try_from(out.0).unwrap()),
-                    Expect::Presence(cb, _) => cb(Presence::try_from(out.0).unwrap()),
-                },
-                (Some(out), None) => panic!("Missing matching expected element: {:?}", out),
-                (None, Some(expected)) => match expected {
-                    Expect::Element(el) => panic!("Missing matching sent element: {:?}", el),
-                    Expect::Iq(_, desc) => panic!("Missing iq: {}", desc),
-                    Expect::Message(_, desc) => panic!("Missing message: {}", desc),
-                    Expect::Presence(_, desc) => panic!("Missing presence: {}", desc),
-                },
-            }
-        }
-    }
-
     fn _send_stanza<E: Into<TestElement> + Send>(&mut self, el: E) -> Result<(), Error> {
-        Ok(self.out_buffer.push_back(el.into()))
+        let out: TestElement = el.into();
+        let expected = self.expect_buffer.pop_front();
+
+        match expected {
+            Some(expected) => match expected {
+                Expect::Element(el) => assert_eq!(String::from(&el), String::from(&out)),
+                Expect::Iq(cb, _) => match Iq::try_from(out.0.clone()) {
+                    Ok(iq) => cb(iq),
+                    _ => panic!(
+                        "Mismatch stanza type. Expected iq, got: {}",
+                        String::from(&out)
+                    ),
+                },
+                Expect::Message(cb, _) => match Message::try_from(out.0.clone()) {
+                    Ok(message) => cb(message),
+                    _ => panic!(
+                        "Mismatch stanza type. Expected message, got: {}",
+                        String::from(&out)
+                    ),
+                },
+                Expect::Presence(cb, _) => match Presence::try_from(out.0.clone()) {
+                    Ok(presence) => cb(presence),
+                    _ => panic!(
+                        "Mismatch stanza type. Expected presence, got: {}",
+                        String::from(&out)
+                    ),
+                },
+            },
+            None => panic!("Missing matching expected element: {:?}", out),
+        }
+
+        Ok(())
     }
 }
 
@@ -254,6 +259,21 @@ impl Stream for TestComponent {
     }
 }
 
+impl Drop for TestComponent {
+    fn drop(&mut self) {
+        // Don't assert if we're already panicking. Rustc displays a huge backtrace when "panicked
+        // while panicking" even when nobody asks for it (RUST_BACKTRACE unset). Let the error
+        // appear if there isn't any other error.
+        if !thread::panicking() {
+            assert_eq!(
+                self.expect_buffer.len(),
+                0,
+                "Remaining expected elements in the buffer"
+            );
+        }
+    }
+}
+
 #[async_trait]
 impl ComponentTrait for TestComponent {
     async fn send_stanza<E: Into<Element> + Send>(&mut self, el: E) -> Result<(), Error> {
diff --git a/src/room.rs b/src/room.rs
index 19e5d54..fe1f898 100644
--- a/src/room.rs
+++ b/src/room.rs
@@ -473,7 +473,6 @@ mod tests {
         )
         .await
         .unwrap();
-        component.assert();
     }
 
     #[tokio::test]
@@ -534,7 +533,6 @@ mod tests {
         )
         .await
         .unwrap();
-        component.assert();
     }
 
     #[tokio::test]
@@ -634,7 +632,6 @@ mod tests {
         )
         .await
         .unwrap();
-        component.assert();
     }
 
     #[tokio::test]
@@ -706,6 +703,5 @@ mod tests {
         )
         .await
         .unwrap();
-        component.assert();
     }
 }
diff --git a/src/tests/iq.rs b/src/tests/iq.rs
index 97f0324..afbb2bf 100644
--- a/src/tests/iq.rs
+++ b/src/tests/iq.rs
@@ -61,5 +61,4 @@ async fn test_iq_unimplemented() {
 
     component.expect(reply);
     handle_stanza(&mut component, &mut rooms).await.unwrap();
-    component.assert();
 }
diff --git a/src/tests/presence.rs b/src/tests/presence.rs
index 2498df0..995c0bc 100644
--- a/src/tests/presence.rs
+++ b/src/tests/presence.rs
@@ -106,7 +106,6 @@ async fn test_join_presence_empty_room() {
     }, "Room subject to participant1");
 
     handle_stanza(&mut component, &mut rooms).await.unwrap();
-    component.assert();
 
     assert_eq!(rooms.len(), 1);
     match rooms.get(&roomjid) {
@@ -160,7 +159,6 @@ async fn test_join_presence_nick_already_assigned() {
     );
 
     handle_stanza(&mut component, &mut rooms).await.unwrap();
-    component.assert();
 
     match rooms.get(&roomjid) {
         Some(room) => assert_eq!(room.occupants.len(), 1),
@@ -263,7 +261,6 @@ async fn test_join_presence_existing_room() {
     }, "Subject for participant2");
 
     handle_stanza(&mut component, &mut rooms).await.unwrap();
-    component.assert();
 
     match rooms.get(&roomjid) {
         Some(room) => assert_eq!(room.occupants.len(), 2),
@@ -330,7 +327,6 @@ async fn test_presence_resync() {
     );
 
     handle_stanza(&mut component, &mut rooms).await.unwrap();
-    component.assert();
 
     match rooms.get(&roomjid) {
         Some(room) => assert_eq!(room.occupants.len(), 2),
@@ -354,7 +350,6 @@ async fn test_leave_non_existing_room() {
     let mut rooms: HashMap<BareJid, Room> = HashMap::new();
     handle_stanza(&mut component, &mut rooms).await.unwrap();
     // The leave should be ignored, there should be no output at all.
-    component.assert();
 }
 
 #[tokio::test]
@@ -394,7 +389,6 @@ async fn test_leave_last_participant() {
 
     handle_stanza(&mut component, &mut rooms).await.unwrap();
 
-    component.assert();
     assert_eq!(rooms.len(), 0);
 }
 
@@ -457,7 +451,6 @@ async fn test_leave_room_not_last() {
     );
 
     handle_stanza(&mut component, &mut rooms).await.unwrap();
-    component.assert();
     assert_eq!(rooms.len(), 1);
     match rooms.get(&roomjid) {
         Some(room) => assert_eq!(room.occupants.len(), 1),
@@ -547,7 +540,6 @@ async fn test_join_msn() {
     component.expect_message(|_| (), "Subject message for participant2");
 
     handle_stanza(&mut component, &mut rooms).await.unwrap();
-    component.assert();
 
     assert_eq!(rooms.len(), 1);
     match rooms.get(&roomjid) {