如何调试" [object ErrorEvent]抛出"我的Karma / Jasmine测试中的错误?

时间:2017-08-16 20:14:59

标签: angular angular-cli karma-jasmine

我有几个失败的测试只输出[object ErrorEvent] thrown。我在控制台中看不到任何可以帮助我查明违规代码的内容。有什么我需要做的事情来追踪这些吗?

[编辑]:我正在运行Karma v1.70,Jasmine v2.7.0

17 个答案:

答案 0 :(得分:110)

要解决此问题,您必须在没有源映射的情况下运行测试作为解决方法:

CLI v6.0.8及更高版本
 --source-map=false

CLI v6.0.x早期版本
 --sourceMap=false

CLI v1.x
 --sourcemaps=false

  

快捷方式ng test -sm=false也可能有效

https://github.com/angular/angular-cli/issues/7296

上有一个未解决的问题

<强>更新: 我也遇到了这个问题,所以我只是迁移到最新的cli并确保所有软件包都在package.json中更新,我也完全重新安装了node_modules所以现在问题已经消失了。

答案 1 :(得分:40)

如果sourcemap = false无效,请尝试 1)打开运行测试的浏览器 2)点击调试按钮 3)打开控制台

错误就在那里

enter image description here

答案 2 :(得分:22)

尝试通过从终端运行测试获得更具描述性的错误消息,如下所示:

ng test -sm=false

在测试中,您可以替换

it('should...')

fit('should...') 

现在只会运行以 fit 开头的测试。 要在运行测试后让浏览器保持打开状态,请运行以下测试:

ng test -sm=false --single-run false

就个人而言,我曾两次遇到此错误。两者都只在调用fixture.detectChanges()时触发。

第一次时间,我通过在.html文件中更安全地使用字符串插值解决了这个问题。

不安全示例:

<p>{{user.firstName}}</p>

安全(r)示例(请注意问号):

<p>{{user?.firstName}}</p>

同样适用于财产绑定:

<p [innerText]="user?.firstName"></p>

第二次时间,我在我的.html文件中使用了DatePipe,但我使用它的mock属性不是日期。

.html文件:

<p>{{startDate | date: 'dd-MM-yyyy'}}</p>

.ts(模拟数据)文件(错误):

let startDate = 'blablah';

.ts(模拟数据)文件(正确):

let startDate = '2018-01-26';

答案 3 :(得分:12)

这是因为茉莉花框架无法处理ErrorEvent类型,因此它不会提取错误消息,而是对该对象调用error.toString()

我刚刚在茉莉花回购中提出了一个问题 https://github.com/jasmine/jasmine/issues/1594

只要它不是固定的,就可以在node_modules文件夹中临时修补已安装的jasmine软件包。就我而言,是

node_modules/jasmine/node_modules/lib/jasmine-core/jasmine.js

,然后从此更改ExceptionFormatter的实现

if (error.name && error.message) {
    message += error.name + ': ' + error.message;
} else {
    message += error.toString() + ' thrown';
}

对此

if (error.name && error.message) {
    message += error.name + ': ' + error.message;
} else if (error.message) {
    message += error.message;
} else {
    message += error.toString() + ' thrown';
}

这有助于发现问题。

答案 4 :(得分:7)

对我来说,这与在一个组件的ngOnInit中解决了一个承诺有关。我必须使用asyncfakeAsync并勾选以及使用spyOn

删除异步服务
beforeEach(async(
  //... initialise testbed and component
))
beforeEach(fakeAsync(
  // ... setup mocks then call:
  component.ngOnInit()
  tick()
  fixture.detectChanges()
))

Angular - How to unit test component with asynchronous service call

答案 5 :(得分:4)

TL; DR:可能与测试路由有关。

我也得到了[object ErrorEvent] thrown。 一小时后,将其追溯到一行代码。

this.username = this.userService.getUser(this.route.snapshot.paramMap.get('id'))[0];

问题在于测试环境试图评估this.route.snapshot.paramMap.get('id')

如果我将其替换为0[object ErrorEvent] thrown就会消失。

我的userService有这样的用户:

public users = [ ["admin", "First name", "Surname", etc... ] ].

所以0只是在索引0获得此用户。

否则,在正常运行我的应用程序时,当用户从我的用户表中选择要编辑的用户时,将评估this.route.snapshot.paramMap.get('id')

因此,在我的HTML中,*ngFor="let user of users; index as i"循环显示所有用户,然后routerLink="/edit/{{i}}",这样您就可以点击每个用户的编辑按钮,点击该按钮时,例如http://localhost:4200/edit/0编辑上述管理员用户的详细信息。

答案 6 :(得分:1)

我遇到了同样的问题。发生此错误的一种方法是当您尝试访问模板中的任何null或undefined时。确保您对这些变量进行安全检查。

例如,当组件加载时未定义config时,这将抛出[object:ErrorEvent]。

<强> template.html

<div *ngIf="config.options">
   .....
   ......
</div>

改为

<div *ngIf="config?.options">
   .....
   ......
</div>

答案 7 :(得分:1)

每个测试用例之后的清洁方法是什么

  afterEach(() => {
    TestBed.resetTestingModule();
  })

答案 8 :(得分:0)

这似乎是一个异步问题,因为在我的一个组件规格中添加了足够的it之后,我能够获得一条有用的错误消息,该错误消息指向该文件和该文件中的行(与paramMap有关。

在测试ParamMap的规范中,我刚刚添加:

  describe('this test', () => {
    it('will succeed', () => {
      expect(true).toBeTruthy();
    });

    it('will succeed', () => {
      expect(true).toBeTruthy();
    });

    it('will succeed', () => {
      expect(true).toBeTruthy();
    });

    it('will succeed', () => {
      expect(true).toBeTruthy();
    });
  });

答案 9 :(得分:0)

对我来说,问题是我在测试中意外地使用了 auth0-lock 库。

答案 10 :(得分:0)

您可能进行了比赛或异步测试,但设置不正确或使用不当。我认为需要修复调试案例并忽略命令行通过。如果错误[object ErrorEvent] thrown间歇出现,请继续刷新业力测试运行器(浏览器),然后确保已正确实现异步条件。

希望这有效。

答案 11 :(得分:0)

  

抛出[对象ErrorEvent]

此错误表明您有未定义的内容。根据我的经验,最简单的调试方法是:

it('should create', () => {
    console.log(component);
    // You can check in the browser log which property is undefined
    });

答案 12 :(得分:0)

就我而言,问题出在服务上,因为在测试运行期间将无法定义对象之一。

服务代码示例类似于下面对dom的访问

  const elem = this.document.querySelector(element) as HTMLElement;
  elem.scrollIntoView({param1: ''});

引用此服务的规范失败,并显示错误“ [对象ErrorEvent]引发”。

我在涉及此的所有规范中嘲笑了服务对象,问题得到解决。

模拟服务

class MockService {
serviceMethod(div) : void {
  testElement = document.querySelector('div') as HTMLElement;
  return testElement;
  } 
}

并在以下提供者中使用此模拟服务对象,

beforeEach(async(() => {

TestBed.configureTestingModule({
  declarations: [Component],
  providers: [
     { provide: Service, useClass: MockService },
    ],
})
  .compileComponents();
}));

答案 13 :(得分:0)

如果您为Karma测试运行程序打开了Chrome窗口,则可以帮助打开开发人员工具并检查其中的控制台。对我来说,这有助于我发现应用程序无法在未定义的数组上使用Array.findIndex方法(因为数据结构是由日期字符串组织的,例如data [2018] [3] [28],并且我碰巧指出了错误的日期),但是测试不仅在错误中停了下来,而且还在继续运行。

答案 14 :(得分:0)

我在proxy.conf.json中定义的应用程序中使用了代理,例如:

'/api': { 'target': 'some path', 'changeOrigin': false }

由于Karma不了解此代理,因此它在控制台中不断出现错误,提示找不到API终结点。 因此,在查看了Karma文档之后,我发现我可以做的就是在karma.conf.js中使用来自proxy.conf.json的相同对象添加“ proxies”属性:

proxies: { '/api': { 'target': 'some path', 'changeOrigin': false }}

控制台中的错误消失了,并且[object errorEvent]也不再抛出。

答案 15 :(得分:0)

对我来说,这是由于未为我所订阅的api定义错误处理程序引起的。

我的修复仅涉及添加代码块以处理以下(err):

it('reports an error to subscribers of api calls if not authenticated', (done) => {
    let obsDataFound = dataService.find(1);
    obsDataFound.subscribe((app) => {
        // not expecting this block to be called
        done();
    }, (err) => {
        // This is the err block that I added that solved the problem
        expect(true).toBeTruthy();
        done();
    });

    let testRequest = httpMock.expectOne({method: 'GET'});
    const mockErrorResponse = { status: 401, statusText: 'Unauthorized test status message' };
    testRequest.flush(appTest, mockErrorResponse);
});

答案 16 :(得分:-1)

最后,什么对我有用:

    TestBed.resetTestingModule();
  })