jest.mock<CreateProductCommandHandler>(
'./commands/create.product.command.handler',
);
jest.mock<ProductRepository>('./infrastructure/product.repository');
describe('ProductController', () => {
let productController: ProductController;
let createProductCommandHandler: CreateProductCommandHandler;
let productRepository: ProductRepository;
let eventPublisher: EventPublisher;
let commandBus: CommandBus;
let queryBus: QueryBus;
let mapper: Mapper;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [AutomapperModule],
controllers: [ProductController],
providers: [
CommandBus,
QueryBus,
AutomapperModule,
CreateProductCommandHandler,
{
provide: ProductRepository,
useValue: productRepository,
},
{
provide: EventPublisher,
useValue: eventPublisher
},
ProductRepository,
],
}).compile();
//mapper = moduleRef.get<Mapper>(typeof(Mapper));
productController = moduleRef.get<ProductController>(ProductController);
productRepository = moduleRef.get<ProductRepository>(ProductRepository);
commandBus = moduleRef.get<CommandBus>(CommandBus);
queryBus = moduleRef.get<QueryBus>(QueryBus);
createProductCommandHandler = moduleRef.get<CreateProductCommandHandler>(
CreateProductCommandHandler,
);
jest.clearAllMocks();
});
Here is the controller class
@Controller()
export class ProductController {
constructor(
private readonly commandBus: CommandBus,
private readonly queryBus: QueryBus,
@InjectMapper() private readonly mapper: Mapper,
) {}
Here is the Automapper profile
@Injectable()
export class ProductProfile extends AutomapperProfile {
constructor(@InjectMapper() mapper: Mapper) {
super(mapper);
}
get profile(): MappingProfile {
return (mapper: Mapper) => {
createMap(mapper, ProductModel, CreateProductCommand);
createMap(mapper, CreateProductCommand, ProductDomain);
createMap(mapper, UpdateProductModel, UpdateProductCommand);
createMap(mapper, UpdateProductCommand, ProductDomain);
createMap(mapper, ProductModel, ProductDomain);
createMap(mapper, ProductDomain, ProductModel);
createMap(mapper, ProductDomain, ProductDocument);
createMap(mapper, ProductDocument, ProductDomain);
createMap(mapper, ProductDocument, ProductModel);
};
}
protected get mappingConfigurations(): MappingConfiguration[] {
return [
extend(FzAbstractModel, FzAbstractCommand),
extend(FzAbstractModel, FzAbstractDomain),
extend(FzAbstractDomain, FzAbstractModel),
extend(FzAbstractDomain, FzAbstractDocument),
extend(FzAbstractDocument, FzAbstractDomain),
];
}
}
I am using @nestjs/cqrs and a service class with automapper injected in controllers and service and trying to run unit test.
Mapper is actually an interface from @automapper/core.
I need a help on mocking and resolving the dependency of automapper. Because when I run the test it throws an error
Nest can't resolve dependencies of the ProductController (CommandBus, QueryBus, ?). Please make sure that the argument automapper:nestjs:default at index [2] is available in the RootTestModule context.
Finally with the help of @MicaelLevi, I implemented this and the mock works fine for automapper. The Automapper Profiles must also be passed in the providers section.
let mapper: Mapper;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [AutomapperModule],
controllers: [ProductController],
providers: [
CommandBus,
QueryBus,
{
provide: getMapperToken(),
useValue: createMapper({
strategyInitializer: classes(),
}),
},
BaseProfile,
ProductProfile,
CreateProductCommandHandler,
{
provide: ProductRepository,
useValue: productRepository,
},
{
provide: EventPublisher,
useValue: eventPublisher,
},
ProductRepository,
],
}).compile();
mapper = moduleRef.get<Mapper>(getMapperToken());