Meine Anwendung verwendet die hyper Kiste, um einige Daten über HTTP zu liefern. Der Kern ist ein Handler-Funktion, wie folgt aus:Wie testet man eine Hyper-Server-HTTP-Handler-Funktion?
struct HttpHandler {}
impl hyper::server::Handler for HttpHandler {
fn handle(&self, req: hyper::server::Request, res: hyper::server::Response) {
res.send(b"Hello").unwrap();
}
}
Hyper wird für jede HTTP-Anforderung diese Funktion aufrufen, die Request
req
und Response
res
Variablen bereitstellt.
Ich möchte meine Einheit handle
Funktion testen, so nenne ich die Funktion, ein Request
und Response
, und behaupten, vorausgesetzt, dass die Response
verwendet worden, die erwarteten Daten zu senden („Hallo“).
Ich versuche, ein Request
Objekt und ein Response
Objekt in die handle
Funktion zu instanziieren. Dafür sind mehrere Abhängigkeiten notwendig, die ich erstellen muss. Dazu kam ich ein Mock NetworkStream
Implementierung bis:
mod tests {
use std::io;
use std::io::prelude::*;
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
use std::time::Duration;
use hyper::server::Handler;
use super::*;
struct MockNetworkStream {}
impl Read for MockNetworkStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
Ok(1)
}
}
impl Write for MockNetworkStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Ok(1)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl hyper::net::NetworkStream for MockNetworkStream {
fn peer_addr(&mut self) -> Result<SocketAddr, io::Error> {
Ok(SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)))
}
fn set_read_timeout(&self, dur: Option<Duration>) -> Result<(), io::Error> {
Ok(())
}
fn set_write_timeout(&self, dur: Option<Duration>) -> Result<(), io::Error> {
Ok(())
}
}
#[test]
fn test_handle() {
let handler = HttpHandler {};
let mut request_mock_network_stream = MockNetworkStream {};
let mut reader = hyper::buffer::BufReader::new(&mut request_mock_network_stream as
&mut hyper::net::NetworkStream);
let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
// The following fails with
// 'tests::test_handle' panicked at 'called `Result::unwrap()` on an `Err` value: Header'
let request = hyper::server::Request::new(&mut reader, socket).unwrap();
let mut headers = hyper::header::Headers::new();
let mut response_mock_network_stream = MockNetworkStream {};
let response = hyper::server::Response::new(&mut response_mock_network_stream,
&mut headers);
handler.handle(request, response);
// I would like to do some assert like this:
// assert_eq!(result, b"Hello");
}
}
Full runnable playground example
jedoch Instanziieren die Request
panics:
// The following fails with
// 'tests::test_handle' panicked at 'called `Result::unwrap()` on an `Err` value: Header'
let request = hyper::server::Request::new(&mut reader, socket).unwrap();
Wo ist der Fehler in meinem Mock-Setup? Gibt es eine einfachere Möglichkeit, eine solche Handler-Funktion ohne so viel Code zu testen?
Das sind keine guten impl von 'Read' und' Write'. .. Das könnte zu anderen Problemen führen. –
Es ist hässlich, aber Sie könnten einfach die interne Implementierung von ['MockStream'] kopieren (https://github.com/hyperium/hyper/blob/0.10.x/src/mock.rs). – Shepmaster