Skip to content

Commit b199cb2

Browse files
committed
Refactor tests to be independent from the adapter
In order to reuse the tests with different adapters, we need the generic test logic to be independent from the adapter (Kurrent). This commit uses type parameters to remove references to Kurrent in the generic test cases so that they can be reused with a different adapter.
1 parent 7d4df73 commit b199cb2

File tree

3 files changed

+73
-92
lines changed

3 files changed

+73
-92
lines changed

tests/integration_tests.rs

Lines changed: 0 additions & 23 deletions
This file was deleted.

tests/kurrent_tests.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
mod test_cases;
2+
3+
use test_cases::*;
4+
use mneme::{ConnectionSettings, EventStreamId, Kurrent};
5+
6+
impl TestStore for Kurrent {
7+
fn create_test_store() -> Self {
8+
let settings = ConnectionSettings::builder()
9+
.host("localhost")
10+
.port(2113)
11+
.tls(false)
12+
.username("admin")
13+
.password("changeit")
14+
.build()
15+
.expect("Failed to build connection settings");
16+
17+
Kurrent::new(&settings).expect("Failed to connect to event store")
18+
}
19+
20+
async fn read_client_events(event_store: &Self, stream_id: EventStreamId) -> Vec<TestEvent> {
21+
let mut stream = event_store.client
22+
.read_stream(stream_id.clone(), &Default::default())
23+
.await
24+
.expect("failed to read stream");
25+
let mut events = vec![];
26+
while let Some(event) = stream.next().await.expect("failed to get next event") {
27+
events.push(
28+
event
29+
.get_original_event()
30+
.as_json::<TestEvent>()
31+
.expect("failed to deserialize event"),
32+
);
33+
}
34+
events
35+
}
36+
}
37+
38+
39+
#[tokio::test]
40+
async fn successful_command_execution_with_no_events_produced() {
41+
test_successful_command_execution_with_no_events_produced::<Kurrent>().await
42+
}
43+
44+
#[tokio::test]
45+
async fn command_rejection_error() {
46+
test_command_rejection_error::<Kurrent>().await
47+
}
48+
49+
#[tokio::test]
50+
async fn successful_execution_with_events_will_record_events() {
51+
test_successful_execution_with_events_will_record_events::<Kurrent>().await
52+
}
53+
54+
#[tokio::test]
55+
async fn existing_events_are_available_to_handler() {
56+
test_existing_events_are_available_to_handler::<Kurrent>().await
57+
}

tests/test_cases.rs

Lines changed: 16 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,13 @@
1-
use mneme::{AggregateState, Command, Error, Event, EventStore, execute};
2-
use mneme::{ConnectionSettings, EventStreamId, Kurrent};
1+
use mneme::{AggregateState, Command, Error, Event, EventStore, EventStreamId, execute};
32
use serde::{Deserialize, Serialize};
43
use std::convert::Infallible;
54
use uuid::Uuid;
65

7-
pub fn create_test_store() -> Kurrent {
8-
let settings = ConnectionSettings::builder()
9-
.host("localhost")
10-
.port(2113)
11-
.tls(false)
12-
.username("admin")
13-
.password("changeit")
14-
.build()
15-
.expect("Failed to build connection settings");
16-
17-
Kurrent::new(&settings).expect("Failed to connect to event store")
18-
}
6+
pub trait TestStore: EventStore + Send {
7+
fn create_test_store() -> Self;
198

20-
pub async fn read_client_events(
21-
client: &eventstore::Client,
22-
stream_id: EventStreamId,
23-
) -> Vec<TestEvent> {
24-
let mut stream = client
25-
.read_stream(stream_id.clone(), &Default::default())
26-
.await
27-
.expect("failed to read stream");
28-
let mut events = vec![];
29-
while let Some(event) = stream.next().await.expect("failed to get next event") {
30-
events.push(
31-
event
32-
.get_original_event()
33-
.as_json::<TestEvent>()
34-
.expect("failed to deserialize event"),
35-
);
36-
}
37-
events
9+
#[allow(async_fn_in_trait)]
10+
async fn read_client_events(event_store: &Self, stream_id: EventStreamId) -> Vec<TestEvent>;
3811
}
3912

4013
#[derive(Clone)]
@@ -212,8 +185,8 @@ impl Event for TestEvent {
212185
}
213186
}
214187

215-
pub async fn test_successful_command_execution_with_no_events_produced() {
216-
let mut event_store = create_test_store();
188+
pub async fn test_successful_command_execution_with_no_events_produced<Adapter: TestStore>() {
189+
let mut event_store: Adapter = TestStore::create_test_store();
217190
let command = NoopCommand::new();
218191
let stream_id = command.event_stream_id();
219192

@@ -226,8 +199,8 @@ pub async fn test_successful_command_execution_with_no_events_produced() {
226199
assert!(result.is_ok());
227200
}
228201

229-
pub async fn test_command_rejection_error() {
230-
let mut event_store = create_test_store();
202+
pub async fn test_command_rejection_error<Adapter: TestStore>() {
203+
let mut event_store: Adapter = TestStore::create_test_store();
231204
let command = RejectCommand::new();
232205
let stream_id = command.event_stream_id();
233206

@@ -255,47 +228,21 @@ pub async fn test_command_rejection_error() {
255228
}
256229
}
257230

258-
pub async fn test_successful_execution_with_events_will_record_events() {
259-
let mut event_store = create_test_store();
231+
pub async fn test_successful_execution_with_events_will_record_events<Adapter: TestStore>() {
232+
let mut event_store: Adapter = TestStore::create_test_store();
260233
let id = Uuid::new_v4();
261234
let command = EventProducingCommand::new(id);
262235

263236
let result = execute(command, &mut event_store, Default::default()).await;
264237
result.expect("failed to execute command");
265238

266-
let mut stream = event_store
267-
.client
268-
.read_stream(EventStreamId(id), &Default::default())
269-
.await
270-
.expect("failed to read stream");
271-
let mut events: Vec<eventstore::ResolvedEvent> = vec![];
272-
while let Some(event) = stream.next().await.expect("failed to get next event") {
273-
events.push(event);
274-
}
239+
let events = TestStore::read_client_events(&event_store, EventStreamId(id)).await;
275240

276-
assert_eq!(events.len(), 2);
277-
278-
let event = events.first().unwrap().get_original_event();
279-
assert_eq!(event.event_type, "TestEvent.One");
280-
assert_eq!(
281-
event
282-
.as_json::<TestEvent>()
283-
.expect("unable to deserialize event"),
284-
TestEvent::One { id }
285-
);
286-
287-
let event = events.get(1).unwrap().get_original_event();
288-
assert_eq!(event.event_type, "TestEvent.Two");
289-
assert_eq!(
290-
event
291-
.as_json::<TestEvent>()
292-
.expect("unable to deserialize event"),
293-
TestEvent::Two { id }
294-
);
241+
assert_eq!(events, vec![TestEvent::One { id }, TestEvent::Two { id }])
295242
}
296243

297-
pub async fn test_existing_events_are_available_to_handler() {
298-
let mut event_store = create_test_store();
244+
pub async fn test_existing_events_are_available_to_handler<Adapter: TestStore>() {
245+
let mut event_store: Adapter = TestStore::create_test_store();
299246
let id = Uuid::new_v4();
300247
let rand_1: u16 = rand::random();
301248
let rand_2: u16 = rand::random();
@@ -315,7 +262,7 @@ pub async fn test_existing_events_are_available_to_handler() {
315262
match execute(command, &mut event_store, Default::default()).await {
316263
Ok(()) => {
317264
assert_eq!(
318-
read_client_events(&event_store.client, EventStreamId(id)).await,
265+
TestStore::read_client_events(&event_store, EventStreamId(id)).await,
319266
vec![
320267
TestEvent::FooHappened { id, value: rand_1 },
321268
TestEvent::BarHappened { id, value: rand_2 },

0 commit comments

Comments
 (0)