Testing an async injectable service

crthompson

I'm trying to set up tests of my @Injectable storage service.

@Injectable()
export class StorageService {...

constructor(private platform: Platform,
  public instanceService: InstanceService,
  private logger: LoggingService,
  private database: SQLite = null) {... //injecting a db mock

I've created several versions of the test that succeed, but I've learned they only succeed because they are async and are misreporting the error.

Here's the setup.

describe('Storage Service tests', () => {
beforeEach(async(() => {
    TestBed.configureTestingModule({
        declarations: [],
        providers: [
            StorageService,
            { provide: Platform, useClass: PlatformMock },
            { provide: InstanceService, useClass: InstanceServiceMock },
            { provide: LoggingService, useClass: LoggingServiceMock },
            { provide: ConfigurationService, useClass: ConfigurationServiceMock },
            { provide: SQLite, useClass: DBMock },
            MockBackend,
            BaseRequestOptions,
            {
                provide: Http,
                useFactory: (mockBackend, options) => {
                    return new Http(mockBackend, options);
                },
                deps: [MockBackend, BaseRequestOptions]
            }
        ],
        imports: [
            HttpModule
        ]
    }).compileComponents();
}));

Here I'm trying to test setFailedImageUpdate

I'm struggling to know how to both inject the service so it initializes and pass in done for the async completion.

it('should set failed image', (done) => {
    let cu = new UnsavedImageUpdate();

    inject([StorageService, MockBackend], (storageService, mockBackend) => {
        storageService.db = new DBMock();
        storageService.setFailedImageUpdate([cu]).then((res) => {
            expect(res).toEqual("1234");
            done();
        })();
    })
});

The error I'm getting on this iteration is:

Error: Timeout - Async callback was not invoked within timeout
specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

How can I set up my test to both inject StorageService and pass in done?

EDIT: Trying to follow @learner's suggestions, I created this:

it('should set failed image', async() => {
    let cu = new UnsavedImageUpdate();
    var storageService = TestBed.get(StorageService);
    storageService.db = new DBMock();
    storageService.setFailedImageUpdate([cu]).then((res) => {
        expect(res).toEqual("1234");
    })
});

The test succeeds, but when I debug into it, I got this error:

'expect' was used when there was no current spec, 
this could be because an asynchronous test timed out 
Preethi

Instead of using inject, you can get the injected service in your test method using TestBed.get(StorageService) and you can use async function from angular testing module which waits for the async operation to complete instead of using done.

Use done like this:

it('should set failed image', (done) => {
    let cu = new UnsavedImageUpdate();
    var storageService = TestBed.get(StorageService);
    storageService.db = new DBMock();
    storageService.setFailedImageUpdate([cu]).then((res) => {
        expect(res).toEqual("1234");
        done();
    })
});

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

JUnit-testing a Spring @Async void service method

Web service unit testing

Testing for exceptions in async methods

spring testing @async method

Ionic2, inject NavController to Injectable Service

using injectable service to set configuration of APP_BASE_HREF

Testing async function with jasmine

Unit testing value of Observable returned from service (using async pipe)

Angular - @Input and @Output vs. Injectable Service

MSUnit Testing Async Hell

@Injectable Service not transferring to Component in Angular 5

Angular service error in injectable

Testing async SQS sendMessage

Injectable ApplicationConfig service

Usage of @Injectable class decorator on service provided by @Global module (in official documentation)

Why is my injectable angular service class not saving class variables as expected?

Why is my @Injectable service created more than once?

Injectable singleton service yet not new()able .net core

using the injectable service in end callback function with interactJS

Jasmine Async Testing

async task testing

Async callback was not invoked within timeout - Unit testing a Typescript & Angular $http service

Angular 2 injectable async execution

How do I Initialize Injectable variable using a service

Angular Service Injection Issue: @Injectable Doesn't Work but Providers Does

How to use an Injectable Service in a custom Validator

How do I make a decorated service injectable?

Angular use a service provided in a shared module not recognizing the injectable

Testing async microservices with no API