在我的Angular 4组件中,我有类似的东西:
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
this.myId = this.route.snapshot.params['myId'];
}
Run Code Online (Sandbox Code Playgroud)
而我正在尝试创建一个假设如下的模拟:
class MockActivatedRoute extends ActivatedRoute {
public params = Observable.of({ myId: 123 });
}
Run Code Online (Sandbox Code Playgroud)
我的测试失败了:
TypeError:无法读取undefined的属性'params'.
我怎么想嘲笑它?我是否误解了正确的用法,ActivatedRoute应该更好地使用router.subscribe我的组件?我看到一些复杂的例子,人们嘲笑快照本身,但对我来说它看起来过于复杂.
测试本身很简单:
describe('ngOnInit', () => {
it('should set up initial state properly',
() => {
const component = TestBed.createComponent(MyComponent).componentInstance;
component.ngOnInit();
expect(component.myId).toEqual('123');
});
});
Run Code Online (Sandbox Code Playgroud)
如果我只是将测试下的方法更改为以下内容 - 测试工作:
ngOnInit() {
//this.myId = this.route.snapshot.params['myId'];
this.route.params.subscribe(params => {
this.myId = params['myId'];
});
}
Run Code Online (Sandbox Code Playgroud)
显然我需要模拟Activated快照,但是有更好的方法吗?
我正在尝试测试访问子级路由参数的Angular Resolver。
我的后卫工作正常,但是我无法轻松创建单元测试,因为我无法创建ActivatedRouteSnapshot带有子级路由(只读属性)。
我的解析器
@Injectable({
providedIn: 'root'
})
export class MyResolverGuard implements Resolve<string> {
constructor() {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): string {
return route.firstChild.paramMap.get('my-param');
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试:
it('should resolve chilren route params', () => {
guard = TestBed.get(MyResolverGuard);
const route = new ActivatedRouteSnapshot();
// Cannot assign children because it's a read only property
route.children = [...];
const myResolverParams = guard.resolve(route, null);
});
Run Code Online (Sandbox Code Playgroud)
除了使用模拟以外,还有其他方法ActivatedRouteSnapshot吗?
我的测试后卫方法好吗?
感谢您分享您的策略。
javascript angular angular-router angular-test angular-testing
请注意,这并非特定于量角器。问题出在Angular 2内置的可测试性服务上,而Protractor恰好使用了该服务。量角器Testability.whenStable通过调用进行调用waitForAngular。我已经打了一些失败的代码。
我的测试代码如下所示:
await renderFooView();
await interactWithFooView();
Run Code Online (Sandbox Code Playgroud)
第二行失败:
Failed: No element found using locator: By(css selector, foo-view)
Run Code Online (Sandbox Code Playgroud)
当量角器继续尝试与之交互的代码时,Angular不会呈现“ foo-view”。
如果我在两者之间添加睡眠,那么它可以工作:
await renderFooView();
await browser.sleep(1000);
await interactWithFooView();
Run Code Online (Sandbox Code Playgroud)
显然我不想那样做。对于我来说,量角器最有价值的是“等待角度”机制,该机制消除了脚本中的“等待X”噪声。我想要的是:
await renderFooView();
await browser.waitForAngular();
await interactWithFooView();
Run Code Online (Sandbox Code Playgroud)
实际上,我永远不必手动执行该中间线。每当我拨打与浏览器互动的电话时,量角器都会自动执行。
做一些挖后,我发现,量角器时进行调用,它工作正常,但在角2次出现潜在的可测试性机制打破。
在Angular 2下,量角器的“ waitForAngular”类似于以下内容:
let rootElement = window.getAllAngularRootElements()[0];
let testability = window.getAngularTestability(rootElement);
testability.whenStable(callbackThatResumesScriptExecution);
Run Code Online (Sandbox Code Playgroud)
换句话说,它调用Angular的,testability.whenStable并且仅在Angular报告其稳定后才恢复执行。如果我在回调中添加一些日志记录:
testability.whenStable(() => {
console.log("isStable:", testability.isStable());
callback();
});
Run Code Online (Sandbox Code Playgroud)
isStable()永远是真正的内部whenStable回调,所以角在肯定什么叫似乎是合适的时间。
但是,如果此回调返回后立即返回,则我isStable()再次轮询,它的值为false。
let pollAngularIsStable = `{ …Run Code Online (Sandbox Code Playgroud) 可以说我有一个简单的模块AppModule,其中包含许多导入,声明和提供程序。现在,我想ListComponent为位于此模块的声明列表中的组件编写测试。ListComponent本身使用的很多(但不是每次)导入AppModule。我这样做是这样的:
import { TestBed } from '@angular/core/testing';
// +same copy-pasted list of imports from `AppModule`
beforeEach(done => {
TestBed.configureTestingModule({
imports: [
// +same copy-pasted list of imports from `AppModule`
],
declarations: [
// +same copy-pasted list of declarations from `AppModule`
],
providers: [
{
provide: Http,
useClass: HttpMock,
},
{
provide: Router,
useClass: RouterMock,
}
// +same copy-pasted list of providers from `AppModule`
]
});
Run Code Online (Sandbox Code Playgroud)
它有效,但是肯定是不正确的方法。我不想复制粘贴太多。也许我可以通过一些方便的方法重用AppModule?伪代码如下:
let appModule = new AppModule();
beforeEach(done …Run Code Online (Sandbox Code Playgroud) angular-module angular-components angular angular-test angular-testing
我正在尝试对该材质对话框进行单元测试,以测试模板是否正在渲染正确的注入对象。正确使用该组件即可正常工作
组件-对话框
export class ConfirmationDialogComponent {
constructor(@Inject(MAT_DIALOG_DATA) private dialogModel: ConfirmationDialogModel) {}
}
Run Code Online (Sandbox Code Playgroud)
对话框模板
<h1 mat-dialog-title *ngIf="dialogModel.Title">{{dialogModel.Title}}</h1>
<div mat-dialog-content>
{{dialogModel.SupportingText}}
</div>
<div mat-dialog-actions>
<button mat-button color="primary" [mat-dialog-close]="false">Cancel</button>
<button mat-raised-button color="primary"[mat-dialog-close]="true" cdkFocusInitial>{{dialogModel.ActionButton}}</button>
</div>
Run Code Online (Sandbox Code Playgroud)
模型-正在注入什么
export interface ConfirmationDialogModel {
Title?: string;
SupportingText: string;
ActionButton: string;
}
Run Code Online (Sandbox Code Playgroud)
单元测试-问题出在哪里
describe('Confirmation Dialog Component', () => {
const model: ConfirmationDialogModel = {
ActionButton: 'Delete',
SupportingText: 'Are you sure?',
};
let component: ConfirmationDialogComponent;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
ConfirmationDialogComponent
],
imports: [
MatButtonModule,
MatDialogModule
],
providers: [ …Run Code Online (Sandbox Code Playgroud) unit-testing karma-jasmine angular-material2 angular angular-testing
我正在对使用其他两个组件的组件进行单元测试。单击按钮时创建其他组件
.html
<div id="homepage-top-div" class="homepage-component-css-grid-container"> ...
<button id="get-question-list-button" [routerLink]="questionListRouterLink" class="btn content-div__button--blue css-grid-item-button-div btn-sm">See Questions</button>
</div>
<div id="practice-component-top-div" class="css-grid-container-div common-styles-div--white"> <!-- 4 rows, 1 column-->
...
<button id="new-question-button" [routerLink]="newQuestionRouterLink" class="btn content-div__button--blue css-grid-item-button-div btn-sm">Create a Question</button>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
.ts
export class HomepageContentComponentComponent implements OnInit {
public questionListRouterLink="/practice-question-list";
public newQuestionRouterLink="/new-practice-question";
constructor() {
}
ngOnInit() {
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个,spec但运行时出现以下错误-Failed: Unexpected directive 'NewPracticeQuestionComponent' imported by the module 'DynamicTestModule'. Please add a @NgModule annotation.
规格是
import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing'; …Run Code Online (Sandbox Code Playgroud) 我正在Component使用其他两个组件进行单元测试。单击按钮时创建其他组件
.html
<div id="homepage-top-div" class="homepage-component-css-grid-container"> ...
<button id="get-question-list-button" [routerLink]="questionListRouterLink" class="btn content-div__button--blue css-grid-item-button-div btn-sm">See Questions</button>
</div>
<div id="practice-component-top-div" class="css-grid-container-div common-styles-div--white"> <!-- 4 rows, 1 column-->
...
<button id="new-question-button" [routerLink]="newQuestionRouterLink" class="btn content-div__button--blue css-grid-item-button-div btn-sm">Create a Question</button>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
.ts
export class HomepageContentComponentComponent implements OnInit {
public questionListRouterLink="/practice-question-list";
public newQuestionRouterLink="/new-practice-question";
constructor() {
}
ngOnInit() {
}
}
Run Code Online (Sandbox Code Playgroud)
我创建了一个规范,但是运行它时出现以下错误- Error: StaticInjectorError[Location]:
NullInjectorError: No provider for Location!
规格是
import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import { HomepageContentComponentComponent } from './homepage-content-component.component';
import …Run Code Online (Sandbox Code Playgroud)