Skip to content

Commit a746312

Browse files
committed
Move doubles to folder and improve them
1 parent c7b7411 commit a746312

File tree

3 files changed

+64
-74
lines changed

3 files changed

+64
-74
lines changed
Lines changed: 10 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,30 @@
11
import { CourseMother } from '../domain/CourseMother';
22
import { CreateCourseRequestMother } from './CreateCourseRequestMother';
33
import { CourseCreatedDomainEventMother } from '../domain/CourseCreatedDomainEventMother';
4-
import { CourseRepository } from '../../../../../src/Contexts/Mooc/Courses/domain/CourseRepository';
5-
import { EventBus } from '../../../../../src/Contexts/Shared/domain/EventBus';
64
import { CourseCreator } from '../../../../../src/Contexts/Mooc/Courses/application/CourseCreator';
7-
import { Course } from '../../../../../src/Contexts/Mooc/Courses/domain/Course';
8-
import { CourseCreatedDomainEvent } from '../../../../../src/Contexts/Mooc/Courses/domain/CourseCreatedDomainEvent';
9-
import { DomainEvent } from '../../../../../src/Contexts/Shared/domain/DomainEvent';
10-
import { CourseId } from '../../../../../src/Contexts/Mooc/Shared/domain/Courses/CourseId';
5+
import CourseRepositoryDouble from '../doubles/CourseRepositoryDouble';
6+
import EventBusDouble from '../doubles/EventBusDouble';
117

128
let repository: CourseRepositoryDouble;
13-
let bus: EventBusDouble;
9+
let eventBus: EventBusDouble;
1410
let creator: CourseCreator;
1511

1612
describe('Course Creator', () => {
1713
beforeEach(() => {
1814
repository = new CourseRepositoryDouble();
19-
bus = new EventBusDouble();
20-
creator = new CourseCreator(repository, bus);
15+
eventBus = new EventBusDouble();
16+
creator = new CourseCreator(repository, eventBus);
2117
});
2218

2319
it('should create a valid course', async () => {
2420
const request = CreateCourseRequestMother.random();
25-
const expectedCourse = CourseMother.fromRequest(request);
26-
const expectedEvent = CourseCreatedDomainEventMother.fromCourse(expectedCourse);
2721

2822
await creator.run(request);
2923

30-
shouldSave(expectedCourse);
31-
shouldPublishDomainEvent(expectedEvent);
24+
const expectedCourse = CourseMother.fromRequest(request);
25+
repository.assertLastSavedCourseIs(expectedCourse);
26+
27+
const expectedEvent = CourseCreatedDomainEventMother.fromCourse(expectedCourse);
28+
eventBus.assertLastPublishedEventIs(expectedEvent);
3229
});
3330
});
34-
35-
const shouldSave = (course: Course) => {
36-
// I am not sure at all if we should remove the recorded events before comparing
37-
// I have done it to prevent the tests to fail if the courses have different events
38-
// or events with different ids
39-
expect(course).toMatchObject(repository.getLastSavedCourseWithoutRecordedEvents());
40-
};
41-
42-
const shouldPublishDomainEvent = (event: CourseCreatedDomainEvent) => {
43-
expect(bus.hasPublishedLastEvent(event)).toBe(true);
44-
};
45-
46-
class EventBusDouble implements EventBus {
47-
private spy = jest.fn();
48-
publish(events: DomainEvent[]): void {
49-
this.spy(events);
50-
}
51-
52-
hasPublishedLastEvent(event: DomainEvent) {
53-
const eventArg: DomainEvent[] = this.spy.mock.calls[0][0];
54-
return this.isSimilarTo(event, eventArg[0]);
55-
}
56-
57-
private isSimilarTo(event1: DomainEvent, event2: DomainEvent) {
58-
const event1Data = this.getDomainAttributes(event1);
59-
const event1DataKeys = Object.keys(event1Data);
60-
const event2Data = this.getDomainAttributes(event2);
61-
const event2DataKeys = Object.keys(event2Data);
62-
63-
if (event1DataKeys.length !== event2DataKeys.length) {
64-
return false;
65-
}
66-
// We are considering that all the info in the event are key: stringValue but
67-
// the value may be an object and then the following comparation is not correct
68-
return event1DataKeys.every(key => event1Data[key] === event2Data[key]);
69-
}
70-
71-
// I am not satisfied with the following "any"
72-
private getDomainAttributes(event: DomainEvent): any {
73-
const { eventId, occurredOn, ...data } = event;
74-
75-
return data;
76-
}
77-
}
78-
79-
class CourseRepositoryDouble implements CourseRepository {
80-
private spySave: jest.Mock = jest.fn();
81-
82-
async save(course: Course) {
83-
this.spySave(course);
84-
}
85-
86-
getLastSavedCourseWithoutRecordedEvents() {
87-
const lastSavedCourse = repository.spySave.mock.calls[0][0];
88-
return new Course(lastSavedCourse.id, lastSavedCourse.name, lastSavedCourse.duration);
89-
}
90-
91-
async search(id: CourseId) {
92-
return null;
93-
}
94-
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { CourseRepository } from '../../../../../src/Contexts/Mooc/Courses/domain/CourseRepository';
2+
import { Course } from '../../../../../src/Contexts/Mooc/Courses/domain/Course';
3+
import { CourseId } from '../../../../../src/Contexts/Mooc/Shared/domain/Courses/CourseId';
4+
5+
export default class CourseRepositoryDouble implements CourseRepository {
6+
private spySave: jest.Mock = jest.fn();
7+
8+
async save(course: Course) {
9+
this.spySave(course);
10+
}
11+
12+
assertLastSavedCourseIs(expected: Course): void {
13+
const saveCalls = this.spySave.mock.calls;
14+
15+
expect(saveCalls.length).toBeGreaterThan(0);
16+
17+
const lastSaveCall = saveCalls[saveCalls.length - 1];
18+
const lastSavedCourse = lastSaveCall[0];
19+
const lastSavedCourseWithoutEvents = new Course(lastSavedCourse.id, lastSavedCourse.name, lastSavedCourse.duration);
20+
21+
expect(expected).toMatchObject(lastSavedCourseWithoutEvents);
22+
}
23+
24+
async search(id: CourseId) {
25+
return null;
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { EventBus } from '../../../../../src/Contexts/Shared/domain/EventBus';
2+
import { DomainEvent } from '../../../../../src/Contexts/Shared/domain/DomainEvent';
3+
4+
export default class EventBusDouble implements EventBus {
5+
private publishSpy = jest.fn();
6+
7+
publish(events: DomainEvent[]): void {
8+
this.publishSpy(events);
9+
}
10+
11+
assertLastPublishedEventIs(expectedEvent: DomainEvent) {
12+
const publishSpyCalls = this.publishSpy.mock.calls;
13+
14+
expect(publishSpyCalls.length).toBeGreaterThan(0);
15+
16+
const lastPublishSpyCall = publishSpyCalls[publishSpyCalls.length - 1];
17+
const lastPublishedEvent = lastPublishSpyCall[0][0];
18+
19+
expect(this.getDataFromDomainEvent(expectedEvent)).toMatchObject(this.getDataFromDomainEvent(lastPublishedEvent));
20+
}
21+
22+
private getDataFromDomainEvent(event: DomainEvent) {
23+
const { eventId, occurredOn, ...attributes } = event;
24+
25+
return attributes;
26+
}
27+
}

0 commit comments

Comments
 (0)