0

[Angular version: 2.4.5]

I'm attempting to write an Angular integration component unit test that contains a service that leverages the built-in Angular HTTP library. I cannot get my Service class to instantiate though: either the Service is undefined or I get "Error: Cannot resolve all parameters for 'RequestOptions'(?)".

I understand that typically you'd mock the backend (have successfully done that in other unit tests) or use Protractor. Other SO questions reference Angular 1 or have answers that just don't seem to work. Starting code:

    @Injectable()
    export class ProjectService {
        projectFeature: IProjectFeature;

        constructor(private http: Http) { }

        getProjects(): Observable<IProjects> {
        return this.http.get("/api/Projects")
            .map((response: Response) => response.json() || {})
            .catch(this.handleError);
         }
    }

     // Jasmine spec file:   
        beforeEach(async(() => {
        TestBed.configureTestingModule({
            providers: [
                Http,
                ProjectService,  // service that leverages HTTP
                ConnectionBackend
                //RequestOptions  // removed b/c otherwise can't find parameters error happens
            ],
            imports: [
               HttpModule
            ] 
        });
    }));

    it('sample test', async(() => {
        var projectService = TestBed.get(ProjectService);
        var comp = new ProjectComponent(projectService);
        comp.ngOnInit();  // internally, calls projectService.getProjects()
        expect(comp.projects[0].name).toEqual("Sample Project Name");
    })); 
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
dotNetkow
  • 5,053
  • 4
  • 35
  • 50
  • You didn't supply HttpModule to TestBed, have you? – Estus Flask Apr 26 '17 at 18:34
  • @estus not currently. I've added it, and updated the code above. Now it fails, saying "can't read property Response of undefined" – dotNetkow Apr 26 '17 at 18:49
  • It's not possible to say what's wrong in your case. Considering that this is integration test, there may be much more code than you've posted. Any way, it is as simple as that (much simpler than [it was in A1](http://stackoverflow.com/a/42331623/3731501)). I've added the answer that illustrates how it's done. – Estus Flask Apr 26 '17 at 21:30
  • Did the answer work out for you? If it did, consider accepting it or providing some feedback otherwise, this will help future SO visitors. – Estus Flask May 08 '17 at 14:15
  • Apologies @estus! Still had difficulties, causing me to rethink my testing strategy for a bit, then I went on vacation, haha. Accepted! Thanks again. – dotNetkow May 14 '17 at 16:27

1 Answers1

2

HttpModule module should be provided in TestBed module configuration. After that, Http performs real XHR requests, no extra actions needed, a demo:

  beforeEach(() => {
    TestBed.resetTestEnvironment();

    TestBed.initTestEnvironment(
      BrowserDynamicTestingModule,
      platformBrowserDynamicTesting()
    );

    TestBed.configureTestingModule({
      imports: [
        HttpModule
      ]
    });

  });

  it('should do XHR', async(inject([Http], (http) => {
    http.get('test.json').subscribe(res => {
      expect(res.json()).toBe(1);
    });
  })));
Estus Flask
  • 206,104
  • 70
  • 425
  • 565