I have a test file that is testing a service that returns data from AngularFireDatabase:
import {TestBed, async} from '@angular/core/testing';
import {ProductService} from './product.service';
import {AngularFireDatabase} from '@angular/fire/database';
import {productsMock} from '../../../../mocks/products.mock';
import {Product} from 'shared';
import {Observable} from 'rxjs';
import {getSnapShotChanges} from 'src/app/test/helpers/AngularFireDatabase/getSnapshotChanges';
let list: Product[];
let key: string = '';
const afDatabaseStub = {
db: jest.fn().mockReturnThis(),
list: jest.fn(() => ({
snapshotChanges: jest.fn().mockReturnValue(getSnapShotChanges(list, true)),
valueChanges: jest.fn(
() => new Observable(sub => sub.next(Object.values(list)))
)
})),
object: jest.fn(() => ({
valueChanges: jest.fn(() => new Observable(sub => sub.next({id: key})))
}))
};
describe('ProductService', () => {
let service: ProductService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{provide: AngularFireDatabase, useValue: afDatabaseStub}]
});
service = TestBed.inject(ProductService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
describe('getAllProducts', () => {
it('should be able to return all products', async(() => {
list = productsMock;
service.getAllProducts().subscribe((products: Product[]) => {
expect(products?.length).toEqual(10);
});
}));
});
it('should be able to return a single product using the firebase id', async(() => {
key = '-MA_EHxxDCT4DIE4y3tW'
const response$ = service.getProductById(key);
response$.subscribe((giveawayProduct: GiveawayProduct) => {
expect(giveawayProduct).toBeDefined();
expect(giveawayProduct.id).toEqual(key);
});
}));
});
The problem I am facing is that I now want to test another service that also uses AngularFireDatabase.
So how can I make this stub more general purpose and put it into a shared helper file that I can use in different specs?
For example, I know you can do useClass instead of useValue:
providers: [{provide: AngularFireDatabase, useClass: afDatabaseStub}]
If it was a class then list and key could be class properties that I could set before running the tests.
But when I try that, I get errors like this:
db.list.object is not a function
db.list(...).snapshotchanges is not a function