英文:
In an Angular Unit Test, how can I mock an entire component, instead of just a class?
问题
我试图对使用子组件的组件进行单元测试。我需要模拟子组件,因为子组件使用CanvasJS来显示图表,而CanvasJS与Jest单元测试不兼容。
目前,我的规范文件中如下所示使用了这个:
```javascript
import { SubComponent } from '../shared/components/sub/sub.component';
import { SubComponentMock } from '../shared/mocks/component/SubComponentMocks';
...
const createComponent = createComponentFactory({
component: PageComponent,
declarations: [ViewComponent],
imports: [],
providers: [
{ provide: SubComponent, useClass: SubComponentMock },
],
});
beforeEach(() => {
jest.restoreAllMocks();
spectator = createComponent();
});
it('should create', () => {
expect(spectator.component).toBeTruthy();
});
我的SubComponentMocks文件包含一个名为 SubComponentMock
的类,该类具有与SubComponent中的函数相同的函数。我遇到了以下错误:
从 'sub.component.ts' 无法找到模块 'canvasjs'
难道模拟不应该导致测试根本不尝试查找该模块吗?它不应该在sub.component.ts中执行任何操作,它应该只访问SubComponentMocks。是否有一种方法可以对整个组件进行模拟,以便测试不会尝试查找canvasjs模块?
<details>
<summary>英文:</summary>
I'm trying to unit test a component that is using a subcomponent. I need to mock the subcomponent because the subcomponent uses CanvasJS to display plots, which doesn't work well with Jest Unit Tests.
Right now, this is being used in my spec file as seen below:
import { SubComponent } from '../shared/components/sub/sub.component';
import { SubComponentMock } from '../shared/mocks/component/SubComponentMocks';
...
const createComponent = createComponentFactory({
component: PageComponent,
declarations: [ViewComponent],
imports: [],
providers: [
{ provide: SubComponent, useClass: SubComponentMock },
],
});
beforeEach(() => {
jest.restoreAllMocks();
spectator = createComponent();
});
it('should create', () => {
expect(spectator.component).toBeTruthy();
});
My SubComponentMocks file contains a class ```SubComponentMock ``` which has functions that are in SubComponent. I am getting the following error:
```Cannot find module 'canvasjs' from 'sub.component.ts'```
Shouldn't the mock cause the test to not try to find that module at all? It shouldn't be doing anything in sub.component.ts, it should only be accessing SubComponentMocks. Is there a way for the whole component to be mocked so the test doesn't try to find the canvasjs module?
</details>
# 答案1
**得分**: 1
在你的规范中添加模拟子组件,如下所示:
```typescript
@Component({
selector: 'sub'
})
class MockComponent {
mockProperty <----- 正在使用的属性
}
在创建组件中执行以下操作:
const createComponent = createComponentFactory({
component: PageComponent,
declarations: [ViewComponent, MockComponent],
imports: [],
providers: [],
});
英文:
add mock subcomponent in your spec like this :-
@Component({
selector:'sub'
})
class MockComponent{
mockProperty <----- which being used
}
and in create component do this :-
const createComponent = createComponentFactory({
component: PageComponent,
declarations: [ViewComponent,MockComponent],
imports: [],
providers: [],
});
答案2
得分: -1
I am familiar with Karma and Jasmine but I assume Jest behaves the same in this regard.
In your use case, I would take advantage of the NO_ERRORS_SCHEMA
. This basically tells Angular, if you see an element in the HTML that you don't recognize, don't worry about it.
import { NO_ERRORS_SCHEMA } from '@angular/core';
......
const createComponent = createComponentFactory({
component: PageComponent,
declarations: [ViewComponent],
imports: [],
schemas: [NO_ERRORS_SCHEMA],
});
The way you are mocking the component right now is how you would mock a service.
Also, Aditya's way might work too but I find NO_ERRORS_SCHEMA
to be better (less work if you don't care about the child components in your unit tests).
Also, look into overrideComponent
and overrideModule
but this maybe only if you're using Angular's methodology for testing.
===== edit ==========
Never mind, it seems like you're using ngneat
for testing. I would leverage componentMocks
property then, not schema
.
英文:
I am familiar with Karma and Jasmine but I assume Jest behaves the same in this regard.
In your use case, I would take advantage of the NO_ERRORS_SCHEMA
. This basically tells Angular, if you see an element in the HTML that you don't recognize, don't worry about it.
import { NO_ERRORS_SCHEMA } from '@angular/core';
......
const createComponent = createComponentFactory({
component: PageComponent,
declarations: [ViewComponent],
imports: [],
schemas: [NO_ERRORS_SCHEMA],
});
The way you are mocking the component right now is how you would mock a service.
Also, Aditya's way might work too but I find NO_ERRORS_SCHEMA
to be better (less work if you don't care about the child components in your unit tests).
Also, look into overrideComponent
and overrideModule
but this maybe only if you're using Angular's methodology for testing.
===== edit ==========
Never mind, it seems like you're using ngneat
for testing. I would leverage componentMocks
property then, not schema
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论