Error when unit testing: “Uncaught (in promise) SyntaxError: Unexpected token o in JSON at position 1”

后端 未结 4 1224
太阳男子
太阳男子 2020-12-10 16:58

I\'d like to unit test a service, however, when running the test, I get the following error:

Uncaught (in promise) SyntaxError: Unexpected token o in

4条回答
  •  自闭症患者
    2020-12-10 17:49

    The error Unexpected token ... in JSON at position 1 actually means that JSON.parse was applied to something that is not valid JSON - a random string or a value that is not a string at all which was coerced to string.

    The message Unexpected token o ... implies that parsed value was most likely an object - which is coerced to [object ...] string.

    The problem is clearly seen here:

    Response
      body: ReadableStream
        locked: true
        __proto__: Object
      bodyUsed: true
      ...
    

    Response object here is an instance of global Response constructor (a part of Fetch API), and the presence of ReadableStream clearly indicates this.

    As it can be seen in Fetch polyfill, all that res.json() does is applying JSON.parse to some value

    this.json = function() {
      return this.text().then(JSON.parse)
    }
    

    which is likely new ResponseOptions object that was erroneously supplied to global Response constructor, hence the error.

    Angular has similarly named Response class which derives its interface from Fetch Response but obviously isn't compatible. The problem is that it was never imported and thus global Response was used instead.

    How to fix

    It should be

    import { Response, ResponseOptions, ... } from '@angular/http';
    

    How to prevent

    Globals are declared in Typescript type definitions, they cannot be undeclared but can be re-declared in custom type definition:

    custom.d.ts

    declare var Headers: undefined;
    declare var Request: undefined;
    declare var Response: undefined;
    declare var URLSearchParams: undefined;
    

    Using globals instead of imported Http classes of the same name will result in type error:

    TS2532: Object is possibly 'undefined'.

    Which is a desirable behaviour as long as Fetch API isn't used in Angular app.

    This is not an issue for HttpClient that replaced Http in Angular 4.3 and doesn't use classes of same names as the ones from Fetch API.

提交回复
热议问题