ws_mock::ws_mock_server

Struct WsMockServer

source
pub struct WsMockServer { /* private fields */ }
Expand description

A mock server that exposes a uri and accepts connections.

Once mocks are mounted to a WsMockServer, if matched against, they will log calls and respond according to their configuration.

§Example: Creating and Matching

Here we start a WsMockServer, create a WsMock that will match on any incoming messages and respond with “Hello World”, and mount it to the server. Once mounted, any messages sent to the server will trigger a response and be recorded.

use futures_util::{SinkExt, StreamExt};
use std::time::Duration;
use tokio::time::timeout;
use tokio_tungstenite::connect_async;
use tokio_tungstenite::tungstenite::Message;
use ws_mock::matchers::Any;
use ws_mock::ws_mock_server::{WsMock, WsMockServer};

#[tokio::main]
pub async fn main() {
    let server = WsMockServer::start().await;

    WsMock::new()
        .matcher(Any::new())
        .respond_with(Message::Text("Hello World".to_string()))
        .expect(1)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (mut send, mut recv) = stream.split();

    send.send(Message::from("some message")).await.unwrap();

    let mut received = Vec::new();
     
    // this times out and continues after receiving one response from the server
    while let Ok(Some(Ok(message))) = timeout(Duration::from_millis(100), recv.next()).await {
        received.push(message.to_string());
    }

    server.verify().await;
    assert_eq!(vec!["Hello World"], received);
}

Implementations§

source§

impl WsMockServer

source

pub async fn start() -> WsMockServer

Start the server on a random port assigned by the operating system.

This creates a new internal state object, starts the server as a task, and waits for the handler to signal readiness before returning the server to the caller.

Examples found in repository?
examples/any_match.rs (line 11)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
pub async fn main() {
    let server = WsMockServer::start().await;

    WsMock::new()
        .matcher(Any::new())
        .respond_with(Message::Text("Hello World".to_string()))
        .expect(1)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (mut send, mut recv) = stream.split();

    send.send(Message::from("some message")).await.unwrap();

    let mut received = Vec::new();

    while let Ok(Some(Ok(message))) = timeout(Duration::from_millis(100), recv.next()).await {
        received.push(message);
    }

    server.verify().await;
    assert_eq!(vec![Message::Text("Hello World".to_string())], received);
}
More examples
Hide additional examples
examples/forwarding_messages.rs (line 11)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
pub async fn main() {
    let server = WsMockServer::start().await;

    let (mpsc_send, mpsc_recv) = mpsc::channel::<Message>(32);

    WsMock::new()
        .forward_from_channel(mpsc_recv)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (_send, ws_recv) = stream.split();

    mpsc_send
        .send(Message::Text("message-1".to_string()))
        .await
        .unwrap();
    mpsc_send
        .send(Message::Text("message-2".to_string()))
        .await
        .unwrap();

    let received = collect_all_messages(ws_recv, Duration::from_millis(250)).await;

    server.verify().await;
    assert_eq!(
        vec![
            Message::Text("message-1".to_string()),
            Message::Text("message-2".to_string())
        ],
        received
    );
}
examples/json_match.rs (line 15)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pub async fn main() {
    let expected_json = json!({"message": "heartbeat"});
    let json_msg = serde_json::to_string(&expected_json).expect("Failed to serialize message");

    let server = WsMockServer::start().await;

    WsMock::new()
        .matcher(JsonExact::new(expected_json))
        .respond_with(Message::Text("heartbeat".to_string()))
        .expect(1)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (mut send, mut recv) = stream.split();

    send.send(Message::from(json_msg)).await.unwrap();

    let mut received = Vec::new();

    while let Ok(Some(Ok(message))) = timeout(Duration::from_millis(100), recv.next()).await {
        received.push(message.to_string());
    }

    server.verify().await;
    assert_eq!(vec!["heartbeat"], received);

    server.verify().await;
}
source

pub async fn get_connection_string(&self) -> String

Returns the ip address and port of the server as format!("{}:{}", ip, port)

source

pub async fn uri(&self) -> String

Returns the uri necessary for a client to connect to this mock server instance.

Examples found in repository?
examples/any_match.rs (line 20)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
pub async fn main() {
    let server = WsMockServer::start().await;

    WsMock::new()
        .matcher(Any::new())
        .respond_with(Message::Text("Hello World".to_string()))
        .expect(1)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (mut send, mut recv) = stream.split();

    send.send(Message::from("some message")).await.unwrap();

    let mut received = Vec::new();

    while let Ok(Some(Ok(message))) = timeout(Duration::from_millis(100), recv.next()).await {
        received.push(message);
    }

    server.verify().await;
    assert_eq!(vec![Message::Text("Hello World".to_string())], received);
}
More examples
Hide additional examples
examples/forwarding_messages.rs (line 20)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
pub async fn main() {
    let server = WsMockServer::start().await;

    let (mpsc_send, mpsc_recv) = mpsc::channel::<Message>(32);

    WsMock::new()
        .forward_from_channel(mpsc_recv)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (_send, ws_recv) = stream.split();

    mpsc_send
        .send(Message::Text("message-1".to_string()))
        .await
        .unwrap();
    mpsc_send
        .send(Message::Text("message-2".to_string()))
        .await
        .unwrap();

    let received = collect_all_messages(ws_recv, Duration::from_millis(250)).await;

    server.verify().await;
    assert_eq!(
        vec![
            Message::Text("message-1".to_string()),
            Message::Text("message-2".to_string())
        ],
        received
    );
}
examples/json_match.rs (line 24)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pub async fn main() {
    let expected_json = json!({"message": "heartbeat"});
    let json_msg = serde_json::to_string(&expected_json).expect("Failed to serialize message");

    let server = WsMockServer::start().await;

    WsMock::new()
        .matcher(JsonExact::new(expected_json))
        .respond_with(Message::Text("heartbeat".to_string()))
        .expect(1)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (mut send, mut recv) = stream.split();

    send.send(Message::from(json_msg)).await.unwrap();

    let mut received = Vec::new();

    while let Ok(Some(Ok(message))) = timeout(Duration::from_millis(100), recv.next()).await {
        received.push(message.to_string());
    }

    server.verify().await;
    assert_eq!(vec!["heartbeat"], received);

    server.verify().await;
}
source

pub async fn verify(&self)

Verify the status of all mocks, and panic if expectations have not been met.

This must be called in order for mock expectations to be verified. Failure to do so, if not also relying on messages sent by the server to verify behavior, will result in faulty tests.

Examples found in repository?
examples/any_match.rs (line 34)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
pub async fn main() {
    let server = WsMockServer::start().await;

    WsMock::new()
        .matcher(Any::new())
        .respond_with(Message::Text("Hello World".to_string()))
        .expect(1)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (mut send, mut recv) = stream.split();

    send.send(Message::from("some message")).await.unwrap();

    let mut received = Vec::new();

    while let Ok(Some(Ok(message))) = timeout(Duration::from_millis(100), recv.next()).await {
        received.push(message);
    }

    server.verify().await;
    assert_eq!(vec![Message::Text("Hello World".to_string())], received);
}
More examples
Hide additional examples
examples/forwarding_messages.rs (line 37)
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
pub async fn main() {
    let server = WsMockServer::start().await;

    let (mpsc_send, mpsc_recv) = mpsc::channel::<Message>(32);

    WsMock::new()
        .forward_from_channel(mpsc_recv)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (_send, ws_recv) = stream.split();

    mpsc_send
        .send(Message::Text("message-1".to_string()))
        .await
        .unwrap();
    mpsc_send
        .send(Message::Text("message-2".to_string()))
        .await
        .unwrap();

    let received = collect_all_messages(ws_recv, Duration::from_millis(250)).await;

    server.verify().await;
    assert_eq!(
        vec![
            Message::Text("message-1".to_string()),
            Message::Text("message-2".to_string())
        ],
        received
    );
}
examples/json_match.rs (line 38)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
pub async fn main() {
    let expected_json = json!({"message": "heartbeat"});
    let json_msg = serde_json::to_string(&expected_json).expect("Failed to serialize message");

    let server = WsMockServer::start().await;

    WsMock::new()
        .matcher(JsonExact::new(expected_json))
        .respond_with(Message::Text("heartbeat".to_string()))
        .expect(1)
        .mount(&server)
        .await;

    let (stream, _resp) = connect_async(server.uri().await)
        .await
        .expect("Connecting failed");

    let (mut send, mut recv) = stream.split();

    send.send(Message::from(json_msg)).await.unwrap();

    let mut received = Vec::new();

    while let Ok(Some(Ok(message))) = timeout(Duration::from_millis(100), recv.next()).await {
        received.push(message.to_string());
    }

    server.verify().await;
    assert_eq!(vec!["heartbeat"], received);

    server.verify().await;
}
source

pub async fn shutdown(&mut self)

Shutdown the server and all associated tasks.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

source§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more