tests ddd lib
This commit is contained in:
parent
ef48e8ae68
commit
b12ba842c0
|
@ -13,11 +13,11 @@ import { Test, TestingModule } from '@nestjs/testing';
|
||||||
import { Prisma } from '@prisma/client';
|
import { Prisma } from '@prisma/client';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
export interface FakeProps {
|
interface FakeProps {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateFakeProps {
|
interface CreateFakeProps {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
import {
|
||||||
|
AggregateID,
|
||||||
|
AggregateRoot,
|
||||||
|
DomainEvent,
|
||||||
|
DomainEventProps,
|
||||||
|
} from '@libs/ddd';
|
||||||
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
|
interface FakeProps {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CreateFakeProps {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeRecordCreatedDomainEvent extends DomainEvent {
|
||||||
|
readonly name: string;
|
||||||
|
|
||||||
|
constructor(props: DomainEventProps<FakeRecordCreatedDomainEvent>) {
|
||||||
|
super(props);
|
||||||
|
this.name = props.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeEntity extends AggregateRoot<FakeProps> {
|
||||||
|
protected readonly _id: AggregateID;
|
||||||
|
|
||||||
|
static create = (create: CreateFakeProps): FakeEntity => {
|
||||||
|
const id = v4();
|
||||||
|
const props: FakeProps = { ...create };
|
||||||
|
const fake = new FakeEntity({ id, props });
|
||||||
|
fake.addEvent(
|
||||||
|
new FakeRecordCreatedDomainEvent({
|
||||||
|
aggregateId: id,
|
||||||
|
name: props.name,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return fake;
|
||||||
|
};
|
||||||
|
|
||||||
|
validate(): void {
|
||||||
|
// not implemented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockLogger = {
|
||||||
|
debug: jest.fn(),
|
||||||
|
log: jest.fn(),
|
||||||
|
error: jest.fn(),
|
||||||
|
warn: jest.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('AggregateRoot Base', () => {
|
||||||
|
it('should define an aggregate root based object instance', () => {
|
||||||
|
const fakeInstance = FakeEntity.create({
|
||||||
|
name: 'someFakeName',
|
||||||
|
});
|
||||||
|
expect(fakeInstance).toBeDefined();
|
||||||
|
expect(fakeInstance.domainEvents.length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should publish domain events', async () => {
|
||||||
|
jest.spyOn(mockLogger, 'debug');
|
||||||
|
const eventEmitter = new EventEmitter2();
|
||||||
|
jest.spyOn(eventEmitter, 'emitAsync');
|
||||||
|
const fakeInstance = FakeEntity.create({
|
||||||
|
name: 'someFakeName',
|
||||||
|
});
|
||||||
|
await fakeInstance.publishEvents(mockLogger, eventEmitter);
|
||||||
|
expect(mockLogger.debug).toHaveBeenCalledTimes(1);
|
||||||
|
expect(eventEmitter.emitAsync).toHaveBeenCalledTimes(1);
|
||||||
|
expect(fakeInstance.domainEvents.length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,47 @@
|
||||||
|
import { Command, CommandProps } from '@libs/ddd';
|
||||||
|
import { ArgumentNotProvidedException } from '@libs/exceptions';
|
||||||
|
|
||||||
|
class FakeCommand extends Command {
|
||||||
|
readonly name: string;
|
||||||
|
|
||||||
|
constructor(props: CommandProps<FakeCommand>) {
|
||||||
|
super(props);
|
||||||
|
this.name = props.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BadFakeCommand extends Command {
|
||||||
|
constructor(props: CommandProps<BadFakeCommand>) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Command Base', () => {
|
||||||
|
it('should define a command based object instance', () => {
|
||||||
|
const fakeCommand = new FakeCommand({ name: 'fakeName' });
|
||||||
|
expect(fakeCommand).toBeDefined();
|
||||||
|
expect(fakeCommand.id.length).toBe(36);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should define a command based object instance with a provided id', () => {
|
||||||
|
const fakeCommand = new FakeCommand({ id: 'some-id', name: 'fakeName' });
|
||||||
|
expect(fakeCommand.id).toBe('some-id');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should define a command based object instance with metadata', () => {
|
||||||
|
const fakeCommand = new FakeCommand({
|
||||||
|
name: 'fakeName',
|
||||||
|
metadata: {
|
||||||
|
correlationId: 'some-correlation-id',
|
||||||
|
causationId: 'some-causation-id',
|
||||||
|
userId: 'some-user-id',
|
||||||
|
timestamp: new Date('2023-06-28T05:00:00Z').getTime(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(fakeCommand.metadata.timestamp).toBe(1687928400000);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an exception if props are empty', () => {
|
||||||
|
expect(() => new BadFakeCommand({})).toThrow(ArgumentNotProvidedException);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue