Strange Unit-Test behaviour in angular-cli generated application - unit-testing

I created an application with angular-cli (latest version version 1.0.0-beta.25.5) and added a simple service:
import { Injectable } from '#angular/core';
import {Headers, Http} from '#angular/http';
import 'rxjs/add/operator/toPromise';
import {Todo} from './todo';
#Injectable()
export class TodoService {
public todoUrl = 'http://localhost:4200/app/todos'; // URL to web api
constructor(public http: Http) {
}
getTodos(): Promise<Todo[]> {
return this.http.get(this.todoUrl)
.toPromise()
.then(response => response.json().data as Todo[])
.catch(this.handleError);
}
handleError(error: any): Promise<any> {
return Promise.reject(error.message || error);
}
}
with a test for it:
import {TestBed, inject} from '#angular/core/testing';
import { TodoService } from './todo.service';
import {Todo} from './todo';
import {BaseRequestOptions, Http} from '#angular/http';
import {MockBackendService} from './mock-backend.service';
import {MockBackend} from '#angular/http/testing';
describe('TodoService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
MockBackend,
BaseRequestOptions,
{
provide: Http,
deps: [MockBackend, BaseRequestOptions],
useFactory: (backend: MockBackend, options: BaseRequestOptions) => {
new MockBackendService().SetUpTodoBackend(backend);
return new Http(backend, options);
}
},
TodoService
]
});
});
it('should return array of todos', inject([TodoService], (service: TodoService) => {
service.getTodos().then((todos: Todo[]) => {
console.log(todos.length);
expect(todos.length).toEqual(100);
expect(todos[0].id).toEqual(11);
console.log('Finished.');
});
}));
});
In MockBackendService I return an array of 10 Todos, so the test should fail as it expects the array to contain 100 todos. When I run my test I get the following result:
LOG: 'mockConnection url:: http://localhost:4200/app/todos'
LOG: 10
LOG: 'Finished.'
Executed 1 of 1 SUCCESS (0.139 secs / 0.126 secs)
So it logs that the array contains 10 results but still passes the test. When I add 2 more "tests":
it('should pass', () => {});
it('should also pass', () => {});
the last test fails with the correct message from my first test:
TodoService should also pass FAILED
Expected 10 to equal 100.
#webpack:///src/app/todo.service.spec.ts:32:6 <- src/test.ts:70258:13 [ProxyZone]
ProxyZoneSpec</ProxyZoneSpec.prototype.onInvoke#webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:54312:20 [ProxyZone]
Zone$1</Zone</Zone.prototype.run#webpack:///~/zone.js/dist/zone.js:113:0 <- src/test.ts:74539:24 [ProxyZone => ProxyZone]
scheduleResolveOrReject/<#webpack:///~/zone.js/dist/zone.js:535:0 <- src/test.ts:74961:52 [ProxyZone]
ProxyZoneSpec</ProxyZoneSpec.prototype.onInvokeTask#webpack:///~/zone.js/dist/proxy.js:103:0 <- src/test.ts:54336:20 [ProxyZone]
Zone$1</ZoneDelegate</ZoneDelegate.prototype.invokeTask#webpack:///~/zone.js/dist/zone.js:274:0 <- src/test.ts:74700:21 [ProxyZone]
Zone$1</Zone</Zone.prototype.runTask#webpack:///~/zone.js/dist/zone.js:151:0 <- src/test.ts:74577:28 [<root> => ProxyZone]
drainMicroTaskQueue#webpack:///~/zone.js/dist/zone.js:433:0 <- src/test.ts:74859:25 [<root>]
Executed 3 of 3 (1 FAILED) (0.344 secs / 0.133 secs)
What am I doing wrong here to get such a strange behaviour? I can recreate that behaviour with a newly generated application, so it seems to be somewhere in my code or in a library I use...

Related

Angular 2 Observable Service Karma Jasmine Unit Test not working

I am a newbie to Angular 2 and Karma + Jasmine unit tests. I cannot figure out what semantic error I have made in order to make this unit test use the mocked response. In the console, when "expect(items[0].itemId).toBe(2);" is run, it says items[0].itemId is undefined.
Would someone be able to help me out or point me in the right direction? Please let me know if you need any additional information. Thanks!
item.ts
export class Item {
itemId: number;
itemName: string;
itemDescription: string;
}
item.service.ts
import { Injectable, Inject } from '#angular/core';
import { Headers, Http } from '#angular/http';
import { Observable } from 'rxjs/Rx';
import { Item } from './item';
#Injectable()
export class ItemService {
private headers = new Headers({'Content-Type': 'application/json'});
constructor(
private http: Http)
{
}
getItems(listOptions: Object): Observable<Item[]> {
return this.http.post('/listItems', listOptions, {headers:this.headers})
.map(response => response.json() as Item[])
}
}
item.service.spec.ts
import { TestBed, fakeAsync, inject, tick } from '#angular/core/testing';
import { MockBackend } from '#angular/http/testing';
import { Http, BaseRequestOptions, Response, ResponseOptions } from '#angular/http';
import { Observable } from 'rxjs/Rx';
import { ItemService } from './item.service';
import { Item } from './item';
describe('ItemService', () => {
let mockResponse, matchingItem, connection;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
ItemService,
MockBackend,
BaseRequestOptions,
{
provide: Http,
useFactory: (backend, defaultOptions) => new Http(backend, defaultOptions),
deps: [MockBackend, BaseRequestOptions]
},
// { provide: XHRBackend, useClass: MockBackend }
]
});
const items = [
{
"itemId":2,
"itemName":"test item1",
"itemDescription":"hello hello"
},
{
"itemId":1,
"itemName":"name2124111121",
"itemDescription":"description212412112"
}
];
mockResponse = new Response(new ResponseOptions({body: {data: items}, status: 200}));
});
describe('getItems', () => {
//Subscribing to the connection and storing it for later
it('should return all the items',inject([ItemService, MockBackend], (service: ItemService, backend: MockBackend) => {
backend.connections.subscribe(connection => {
connection.mockRespond(mockResponse);
});
service.getItems({isActive: true, sortColumn: "lastModifiedDateUtc", sortOrder: "desc"})
.subscribe((items: Item[]) => {
expect(items.length).toBe(2);
});
}));
});
});
Plunkr: https://plnkr.co/edit/m7In2eVh6oXu8VNYFf9l?p=preview
(There are some errors with the Plunkr I need help with as well but the main files are there)
The mockResponse body did not match the actual response body, that is why I was getting the error.
mockResponse = new Response(new ResponseOptions({body: {data: items}, status: 200})); should be mockResponse = new Response(new ResponseOptions({body: items, status: 200}));

"Error: No provider for router" while writing Karma-Jasmine unit test cases

We have done one angular2 project set up and inside that created one module (my-module) and inside that module created one component (my-new-component) using following cmd commands:
ng new angular2test
cd angular2test
ng g module my-module
ng generate component my-new-component
After creating the set up and all components, we ran ng test command from cmd inside angular2test folder.
The below file is our my-new-component.component.ts file:
import { Component, OnInit } from '#angular/core';
import { Router, Routes, RouterModule } from '#angular/router';
import { DummyService } from '../services/dummy.service';
#Component({
selector: 'app-my-new-component',
templateUrl: './my-new-component.component.html',
styleUrls: ['./my-new-component.component.css']
})
export class MyNewComponentComponent implements OnInit {
constructor(private router : Router, private dummyService:DummyService) { }
ngOnInit() {
}
redirect() : void{
//this.router.navigate(['/my-module/my-new-component-1'])
}
}
The below file is our my-new-component.component.spec.ts file:
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { RouterTestingModule } from '#angular/router/testing';
import {NgbModule} from '#ng-bootstrap/ng-bootstrap';
import { DummyService } from '../services/dummy.service';
import { MyNewComponentComponent } from './my-new-component.component';
describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, NgbModule.forRoot(), DummyService],
declarations: [ MyNewComponentComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
We are getting the below cmd error while running the ng test command:
Chrome 54.0.2840 (Windows 7 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.593 secs / 2.007 secs)
Chrome 54.0.2840 (Windows 7 0.0.0) MyNewComponentComponent should create FAILED
Failed: Unexpected value 'DummyService' imported by the module 'DynamicTestModule'
Error: Unexpected value 'DummyService' imported by the module 'DynamicTestModule'
We have updated the component file and the spec file. Pleased find below the code snippet.
The below file is our my-new-component.component.ts file:
import { Component, OnInit } from '#angular/core';
import { Router, Routes, RouterModule } from '#angular/router';
import { DummyService } from '../services/dummy.service';
#Component({
selector: 'app-my-new-component',
templateUrl: './my-new-component.component.html',
styleUrls: ['./my-new-component.component.css']
})
export class MyNewComponentComponent implements OnInit {
constructor(private router : Router, private dummyService:DummyService, public fb: FormBuilder) {
super(fb);
}
ngOnInit() {
}
redirect() : void{
//this.router.navigate(['/my-module/my-new-component-1'])
}
}
The below file is our my-new-component.component.spec.ts file:
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { FormsModule, FormGroup, FormBuilder, Validators, ReactiveFormsModule} from '#angular/forms';
import { SplitPipe } from '../../common/pipes/string-split.pipe';
import { RouterTestingModule } from '#angular/router/testing';
import { DummyService } from '../services/dummy.service';
import { MyNewComponentComponent } from './my-new-component.component';
describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, DummyService ,HttpModule, FormBuilder],
declarations: [ MyNewComponentComponent, SplitPipe]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
But while running the ng test command, we are getting the below error.
09 12 2016 09:13:48.987:WARN [karma]: No captured browser, open http://localhost:9876/
09 12 2016 09:13:49.008:INFO [karma]: Karma v1.2.0 server started at http://localhost:9876/
09 12 2016 09:13:49.010:INFO [launcher]: Launching browser Chrome with unlimited concurrency
09 12 2016 09:13:49.420:INFO [launcher]: Starting browser Chrome
09 12 2016 09:13:58.642:INFO [Chrome 54.0.2840 (Windows 7 0.0.0)]: Connected on socket /#QZ9LSSUVeK6KwNDlAAAA with id 46830907
Failed: Unexpected value 'FormBuilder' imported by the module 'DynamicTestModule'
Error: Unexpected value 'FormBuilder' imported by the module 'DynamicTestModule'
You need to import RouterTestingModule when setting up the test module.
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { RouterTestingModule } from '#angular/router/testing';
import { MyNewComponentComponent } from './my-new-component.component';
describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [ MyNewComponentComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Edit: example with mock DummyService
/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { By } from '#angular/platform-browser';
import { DebugElement } from '#angular/core';
import { RouterTestingModule } from '#angular/router/testing';
import { MyNewComponentComponent } from './my-new-component.component';
// import the service
import { DummyService } from '../dummy.service';
// mock the service
class MockDummyService extends DummyService {
// mock everything used by the component
};
describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [MyNewComponentComponent],
providers: [{
provide: DummyService,
useClass: MockDummyService
}]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
Add RouterTestingModule for configureTestingModule testCase
==> imports: [RouterTestingModule],
import {RouterTestingModule} from '#angular/router/testing';
beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule], // <====
providers: [],
declarations: [],
});
});
I get the same kind of error and I want to share my solution to help others
The Error I get in Karma
error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'RouterModule', 'Router', 'Function', 'Function' ] })
NullInjectorError: R3InjectorError(DynamicTestModule)[RouterModule -> Router -> Function -> Function]:
NullInjectorError: No provider for Function!
inventory-view.component.ts
#Component({
selector: 'app-inventory-view',
templateUrl: './inventory-view.component.html',
styleUrls: ['./inventory-view.component.scss'],
animations: []
})
export class InventoryViewComponent implements OnInit, AfterViewInit, OnDestroy {
constructor(
public router: Router, // <--- here was the problem
public activatedRoute: ActivatedRoute
) { }
In my test file
inventory-view.component.spec.ts
import { HttpClientModule } from '#angular/common/http';
import { waitForAsync, ComponentFixture, TestBed } from '#angular/core/testing';
import { RouterTestingModule } from '#angular/router/testing';
import { ActivatedRoute, convertToParamMap, Router } from '#angular/router';
const ActivatedRouteSpy = {
snapshot: {
paramMap: convertToParamMap({
some: 'some',
else: 'else',
})
},
queryParamMap: of(
convertToParamMap({
some: 'some',
else: 'else',
})
)
};
const RouterSpy = jasmine.createSpyObj(
'Router',
['navigate']
);
describe('InventoryViewComponent', () => {
let component: InventoryViewComponent;
let fixture: ComponentFixture<InventoryViewComponent>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule,
RouterTestingModule,
],
declarations: [ InventoryViewComponent ],
providers: [
{ provide: ActivatedRoute, useValue: ActivatedRouteSpy },
{ provide: Router, useValue: RouterSpy }
]
})
.compileComponents();
}));
beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(InventoryViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});

mockRespond method inside beforeEach invokes later than XHR to backend inside test

I am trying to write Jasmine tests using MockBackend from Angular2.
Here is the code that I write to test a service which communicate with backend:
import { inject, TestBed } from '#angular/core/testing';
import {VehicleCategoryService} from './VehicleCategoryService';
import { BaseRequestOptions, Response, ResponseOptions, Http } from '#angular/http';
import { MockBackend, MockConnection } from '#angular/http/testing';
import {HttpService} from "../../api/HttpService";
import {ApplicationService} from "../../api/ApplicationService";
describe('VehicleCategoryService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [VehicleCategoryService,BaseRequestOptions, MockBackend, ApplicationService, {
provide: HttpService,
useFactory: (backend, options, applicationService) => {
return new HttpService(backend, options, applicationService);
},
deps: [MockBackend, BaseRequestOptions, ApplicationService],
}],
});
});
beforeEach(inject([MockBackend], (backend: MockBackend) => {
const baseResponse = new Response(new ResponseOptions({ body: '{"Name":"MiniVan"}' }));
backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
}));
it('should be defined', inject([VehicleCategoryService], (vehicleCategoryService: VehicleCategoryService) => {
expect(vehicleCategoryService).toBeDefined();
}));
it('should return response when querying vehicleCategories', inject([VehicleCategoryService], (vehicleCategoryService: VehicleCategoryService) => {
vehicleCategoryService.query().subscribe((res: Response) => {
expect(res['Name']).toBe('MiniVan');
});
}));
});
http://stackoverflow.com/questions/ask#
HttpService here is a service that extends from built-in Http Angular2 service. query() method returns Observable as a usual Http do.
Debugging issue demonstarte that mockRespond() method inside subscription invokes later than actual call to backend that is why I receive undefined response. How can I solve this problem?

Error during mocking the service for Angular2 application unit test

I've created a component which I'm trying to test using Karma and Jasmine. Everything works fine for other components that doesn't have services injected by DI. But this one throws an error without any message and just with a stack.
Here's the component:
import {Component} from 'angular2/core';
import {Application} from './application';
import {ApplicationsService} from './applications.service';
#Component({
selector: 'applications-selector',
styles: [require('./applications-selector.scss')],
template: require('./applications-selector.html'),
providers: [ApplicationsService]
})
export class ApplicationsSelectorComponent {
applications: Application[];
selectedWeek: number;
selectedApplications: Application[];
selectedCycle: string;
constructor(private _applicationsService: ApplicationsService) {
this.getApplications();
}
getApplications() {
this._applicationsService.getApplications().then(applications => this.applications = applications);
}
}
And here's the unit test for this component:
import {
it,
inject,
injectAsync,
describe,
beforeEachProviders,
TestComponentBuilder
} from 'angular2/testing';
import {provide} from 'angular2/core';
import {ApplicationsSelectorComponent} from './applications-selector.component';
import {ApplicationsService} from './applications.service';
class ApplicationsServiceMock {
getApplications() {
return ['ABC', 'XYZ'];
}
}
describe('ApplicationsSelectorComponent', () => {
beforeEachProviders(() => [
provide(ApplicationsService, { useClass: ApplicationsServiceMock }),
ApplicationsSelectorComponent
]);
it('should have empty default values', inject([ApplicationsSelectorComponent], (component) => {
expect(component.selectedWeek).toBe(undefined);
expect(component.selectedApplications).toBe(undefined);
expect(component.selectedCycle).toBe(undefined);
}));
});
And here's an error that I get as soon as I run this test:
ApplicationsSelectorComponent
× should have empty default values
PhantomJS 2.1.1 (Windows 7 0.0.0)
_instantiateProvider#d:/git/gatekeeper/web/spec-bundle.js:11896:38 <- webpack:///angular2/src/core/di/injector.ts:770:31
_new#d:/git/gatekeeper/web/spec-bundle.js:11885:42 <- webpack:///angular2/src/core/di/injector.ts:759:37
getObjByKeyId#d:/git/gatekeeper/web/spec-bundle.js:11495:55 <- webpack:///angular2/src/core/di/injector.ts:356:44
_getByKeyDefault#d:/git/gatekeeper/web/spec-bundle.js:12083:51 <- webpack:///angular2/src/core/di/injector.ts:977:44
_getByKey#d:/git/gatekeeper/web/spec-bundle.js:12029:42 <- webpack:///angular2/src/core/di/injector.ts:914:35
get#d:/git/gatekeeper/web/spec-bundle.js:11704:31 <- webpack:///angular2/src/core/di/injector.ts:577:26
d:/git/gatekeeper/web/spec-bundle.js:9128:74 <- webpack:///angular2/src/testing/test_injector.ts:151:52
map#[native code]
apply#[native code]
call#[native code]
call#[native code]
map#d:/git/gatekeeper/web/spec-bundle.js:2377:21 <- webpack:///~/es6-shim/es6-shim.js:1113:0
execute#d:/git/gatekeeper/web/spec-bundle.js:9128:39 <- webpack:///angular2/src/testing/test_injector.ts:151:34
execute#d:/git/gatekeeper/web/spec-bundle.js:9017:27 <- webpack:///angular2/src/testing/test_injector.ts:42:22
d:/git/gatekeeper/web/spec-bundle.js:8393:58 <- webpack:///angular2/src/testing/testing.ts:137:49
_instantiate#d:/git/gatekeeper/web/spec-bundle.js:12003:87 <- webpack:///angular2/src/core/di/injector.ts:883:67
An error occurs on inject([ApplicationsSelectorComponent] statement. As soon as I remove it, there's no error, but I need this component to perform tests on it.
What can cause this injection error?
It seems like you're trying to inject components the same way as providers which will not work.
Here is complete minimal example of mocking providers for specific component:
class ApplicationsService {
getApplications() {
return ['ABC'];
}
}
class ApplicationsServiceMock {
getApplications() {
return ['ABC', 'XYZ'];
}
}
#Component({
selector: 'apps',
template: '',
providers: [ApplicationsService]
})
class ApplicationsSelectorComponent {
constructor(private apps: ApplicationsService) {}
}
describe('App', () => {
describe('ApplicationsSelectorComponent', () => {
beforeEach(injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.overrideProviders(ApplicationsSelectorComponent, [provide(ApplicationsService, { useClass: ApplicationsServiceMock })])
.createAsync(ApplicationsSelectorComponent)
.then((componentFixture: any) => {
this.component = componentFixture;
});
}));
it('should have empty default values', () => {
expect(this.component.componentInstance.apps.getApplications()).toEqual(['ABC', 'XYZ'])
});
});
});
Finally, it turned out that all the setup was correct but I was just returning incorrect value from ApplicationsServiceMock. Base service is returning Promise and I was returnig just an array of value in my mock. That's why when this line this._applicationsService.getApplications().then(applications => this.applications = applications); was executed from constructor no then method on array could be found. And tests were failing.
As soon as I've fixed return value from my mock everything works fine.
Here's working code for my test:
import {
it,
beforeEach,
injectAsync,
describe,
TestComponentBuilder
} from 'angular2/testing';
import {Component, provide} from 'angular2/core';
import {Application} from './application';
import {ApplicationsService} from './applications.service';
import {ApplicationsSelectorComponent} from './applications-selector.component';
class ApplicationsServiceMock {
getApplications() {
return Promise.resolve([{ 'id': 1, 'name': 'TST', 'project': 'PRJ' }]);
}
}
describe('ApplicationsSelectorComponent', () => {
beforeEach(injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
return tcb
.overrideProviders(ApplicationsSelectorComponent, [provide(ApplicationsService, { useClass: ApplicationsServiceMock })])
.createAsync(ApplicationsSelectorComponent)
.then((componentFixture: any) => {
this.component = componentFixture;
});
}));
it('should have empty default values', () => {
expect(this.component.componentInstance._applicationsService.getApplications().then(apps => { apps.toEqual([{ 'id': 1, 'name': 'TST', 'project': 'PRJ' }]) }));
});
});

Jasmine gives Cannot read property 'getXHR' of null for Angular 2 unit test

I have found many examples online of unit testing Angular 2 with a http call. However when I make my own test and run it Jasmine it gives me an error:
http Http .request() should accept a fully-qualified request as its only parameter
Failed: Cannot read property 'getXHR' of null
import {
afterEach,
beforeEach,
ddescribe,
describe,
expect,
iit,
inject,
injectAsync,
it,
xit
} from "angular2/testing";
import {Injector, provide} from "angular2/core";
import {MockBackend, MockConnection} from "angular2/src/http/backends/mock_backend";
import {
BaseRequestOptions,
ConnectionBackend,
Request,
RequestMethod,
RequestOptions,
Response,
ResponseOptions,
URLSearchParams,
JSONP_PROVIDERS,
HTTP_PROVIDERS,
XHRBackend,
JSONPBackend,
Http,
Jsonp
} from "angular2/http";
import {Observable} from "rxjs/Observable";
import {Subject} from "rxjs/Subject";
describe("http", () => {
let url = "http://foo.bar";
let http: Http;
let injector: Injector;
let backend: MockBackend;
let baseResponse;
let jsonp: Jsonp;
beforeEach(() => {
injector = Injector.resolveAndCreate([
BaseRequestOptions,
MockBackend,
provide(
Http,
{
useFactory: function(backend: ConnectionBackend, defaultOptions: BaseRequestOptions) {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
}),
provide(
Jsonp,
{
useFactory: function(backend: ConnectionBackend, defaultOptions: BaseRequestOptions) {
return new Jsonp(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions]
})
]);
http = injector.get(Http);
jsonp = injector.get(Jsonp);
backend = injector.get(MockBackend);
baseResponse = new Response(new ResponseOptions({body: "base response"}));
});
afterEach(() => backend.verifyNoPendingRequests());
describe("Http", () => {
describe(".request()", () => {
it("should return an Observable",
() => { expect(http.request(url)).toBeAnInstanceOf(Observable); });
it("should accept a fully-qualified request as its only parameter",
inject([injectAsync], (async) => {
backend.connections.subscribe(c => {
expect(c.request.url).toBe("https://google.com");
c.mockRespond(new Response(new ResponseOptions({body: "Thank you"})));
async.done();
});
http.request(new Request(new RequestOptions({url: "https://google.com"})))
.subscribe((res) => {});
}));
});
});
});
Any thoughts what I am doing wrong here?
You currently (beta.1) need to set the BrowserDomAdapter before running a unit test in Angular 2.
Using karma-test.shim.js
That can be done by adding karma-test.shim.js to your project, which contains the appropriate initialization:
System.import('angular2/src/platform/browser/browser_adapter')
.then(function(browser_adapter) {
browser_adapter.BrowserDomAdapter.makeCurrent();
})
Note that this should be done for you if you are using angular-cli.
Directly in the unit-test
Or directly in the unit test, by adding an import:
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
And later setting the DOM Adapter
BrowserDomAdapter.makeCurrent();