Mocking imported modules for a service - unit-testing

Suppose i want to write a unit test for a service which depends on services of another module.
Now here is my question. Is there any way to write my test so that i mock the module that MyService depends on such that i can use it in my unit test like this:
const moduleRef = await Test.createTestingModule({
imports: [
MockedModule,
],
providers: [
MyService,
],
});
Or i have to write a mock for each dependency service and use them like this:
const moduleRef = await Test.createTestingModule({
providers: [
MyService,
{
provider: DependencyService,
useClass: DependencyServiceMock,
}
],
});

I suppose it would be possible to use a MockModule that provides and exports the same dependencies that the service would normally depend on. I haven't heard of someone trying that yet, but I don't see why it wouldn't work. So if you have
#Injectable()
export class MyService {
constructor(private readonly depService: DependencyService) {}
...
}
Then in your mock module you would need
#Module({
providers: [{
provide: DependencyService,
useClas: DependencyServiceMock,
}],
exports: [DependencyService],
})
export class MockedModule {}
And in your test you would need to do
beforeEach(async () => {
const app = await Test.createTestModule({
imports: [MockedModule],
providers: [MySerivce],
}).compile();
});
...

Related

Is it possible to deploy a NestJS (non-http) micro-service on AWS lambda?

I've written a microservice using NestJS. (Actually two microservices they using the Same Module in one APP structure.)
The North-Bound of microservice is using GRPC and the east-west using RabbitMQ.
North Bound:
const northBound = await NestFactory.createMicroservice<MicroserviceOptions>(
MyModule,
{
transport: Transport.GRPC,
options: {
package: 'mypackage',
protoPath: join(__dirname, 'domain/myservice.proto'),
url: `0.0.0.0:${MY_GRPC_PORT}`,
loader: { keepCase: true, defaults: true },
},
logger: northBoundLogger,
},
);
East-West:
const eastwest = await NestFactory.createMicroservice<MicroserviceOptions>(
MyModule,
{
transport: Transport.RMQ,
options: {
urls: [`amqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}#${RABBITMQ_HOST}`],
queue: RABBITMQ_MY_QUEUE,
queueOptions: {
durable: true,
},
noAck: true,
},
logger: eastwestLogger,
},
);
I can't find out any example on the web which has deployed a non-HTTP nestjs micro-service using serverless framework on AWS lambda.
Is this possible?

How to use a dependency that uses "require" when building an app with Vite?

I have an app (Vite + React) that depends on a library that makes use of dynamic imports in the form of:
const { T } = useLocale(({ locale }) => require(`./i18n/${locale}.json`));
Unfortunately, I can't seem to be able to build my app due to this line. When I attempt to build with Vite, I get errors such as:
Not supported dynamic import, file:/Users/borne/Work/prototype/node_modules/#internal/top-navigation/es/Navigation.js
I added the legacy plugin to my configs, as well as the CommonJs solution as described here:
https://www.npmjs.com/package/#originjs/vite-plugin-commonjs
But it didn't seem to change anything.
This is my config:
import {defineConfig} from 'vite';
import react from '#vitejs/plugin-react';
import babel from 'vite-plugin-babel';
import { viteCommonjs, esbuildCommonjs } from '#originjs/vite-plugin-commonjs';
import legacy from '#vitejs/plugin-legacy';
const fs = require('fs');
export default defineConfig({
plugins: [
viteCommonjs(),
babel(),
react({
babel: {
parserOpts: {
plugins: ['decorators-legacy']
}
},
}),
legacy({
targets: ['defaults', 'not IE 11']
}),
],
optimizeDeps: {
esbuildOptions: {
plugins: [
esbuildCommonjs([
'#internal/top-navigation',
]),
],
},
},
server: {
hmr: {
clientPort: 443,
},
https: {
key: fs.readFileSync('./.cert/key.pem'),
cert: fs.readFileSync('./.cert/cert.pem'),
},
},
define: {
'process.env': {},
'global': {}
}
})
What am I missing?

angular2 testing: add latency to mock http backend

I have a service that gets data from two different backends (database over http request and live data over socket.io) and then publishes this data as a single stream. When testing this service, I would like to be able to control the delay of the mock http service, so that I can play through different kinds of racing conditions. Currently I'm doing this:
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
DataService,
{
provide: IoService,
useClass: MockIoService
},
{
provide: Http,
useFactory: (mockBackend, options) => {
return new Http(mockBackend, options);
},
deps: [MockBackend, BaseRequestOptions]
},
MockBackend,
BaseRequestOptions
]
});
});
it('should get data from http backend', async(inject([DataService, MockBackend, IoService], (service: DataService, mockBackend, ioService) => {
const mockResponse = {
data: [
{ id: 0, text: 'httpData', start: 0, stop: 1 }
]
};
mockBackend.connections.subscribe((connection) => {
connection.mockRespond(new Response(new ResponseOptions({
body: JSON.stringify(mockResponse)
})));
});
service.subscribe('test').subscribe((data) => {
expect(data.text).toBe('httpData');
});
})));
This works but again, I would like to be able to define a delay for the MockBackend so that the response comes after a fixed number of seconds. Is that possible and if yes, how?

How to set the MockBackend status code?

For an HTTP test I've got these providers ..
providers: [
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (pBackend: MockBackend, pOptions: BaseRequestOptions) => {
return new Http(pBackend, pOptions);
},
deps: [MockBackend, BaseRequestOptions]
}
]
I can mock a success response ..
let backend = injector.get(MockBackend);
backend.connections.subscribe(
(connection: MockConnection) => {
connection.mockRespond(new Response(
new ResponseOptions({
body: {mydata:'somedata'}
}
)));
});
and an error response ..
let backend = injector.get(MockBackend);
backend.connections.subscribe(
(connection: MockConnection) => {
connection.mockError(new Error('error'));
});
but please, how do i mock a non 200 response. E.G. how do I respond with HTTP status code 418 for example?
Thanks
Just add a status property to the ResponseOptions
new ResponseOptions({
body: {mydata:'somedata'},
status: 418
})
See the docs for other properties

Torii Not injecting 'session' EmberJS 2.0

I keep receiving the error that the session var is not defined. I've looked at other answers on here about restarting ember serve to remove any caching issues but I've tried that multiple times and I've followed the emberfire guide to the letter. Does anyone have any idea what could be going wrong? The authentication succeeds but the session doesn't get bound to. Here are my files:
/app/routes/application.js
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.query('post', {
orderBy: 'timestamp',
limitToLast: 3
});
},
actions: {
authenticate: function(username, pass) {
this.get('session').open('firebase', {
provider: "password",
email: username,
password: pass
}).then(function (data) {
console.log(data.currentUser);
console.log(session);
});
}
}
});
/app/torii-adapters
import Ember from 'ember';
import ToriiFirebaseAdapter from 'emberfire/torii-adapters/firebase';
export default ToriiFirebaseAdapter.extend({
firebase: Ember.inject.service()
});
/config/environment.js
var ENV = {
modulePrefix: 'website',
environment: environment,
contentSecurityPolicy: { 'connect-src': "'self' https://auth.firebase.com wss://*.firebaseio.com" },
firebase: 'https://REMOVED.firebaseio.com/',
torii: {
sessionServiceName: 'session'
},
baseURL: '/',
locationType: 'auto',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. 'with-controller': true
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
}
};
I was having the same issue following the tutorial for emberfire. I solved the issue by explicitly install torii via npm:
npm install torii
Restarted the server and all is well.