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 { v4 } from 'uuid';
|
||||
|
||||
export interface FakeProps {
|
||||
interface FakeProps {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface CreateFakeProps {
|
||||
interface CreateFakeProps {
|
||||
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