Lançado · em melhoria
Guia de Angular · 5/6
Por enquanto, este capítulo está disponível apenas em inglês.
Angular projects come with unit testing already configured, and the CLI can add an end-to-end (e2e) framework on request. This chapter covers running tests, testing components and services with TestBed, mocking HTTP, and browser-level e2e tests.
Test files sit next to the code they test and end in .spec.ts. ng test runs them with the runner configured in the test target of angular.json:
ng test
ng test --watch=false
ng test --helpWhich runner you get depends on when the project was created. Recent CLI versions set up Vitest for new projects, while projects created with older versions use Karma with the Jasmine framework in a real browser. Both use the same describe, it, beforeEach and expect structure, and Angular's TestBed works the same way in either, so the examples below run on both. Mocking helpers differ: Jasmine has jasmine.createSpy() and spyOn(), while Vitest has vi.fn() and vi.spyOn(). Options such as code coverage also depend on the runner; ng test --help lists what your project supports.
TestBed creates a small Angular environment for a test. Import the standalone component, create it, interact with the DOM and check the result. This test targets the Counter component from the core concepts chapter:
import { TestBed } from '@angular/core/testing';
import { Counter } from './counter';
describe('Counter', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({ imports: [Counter] }).compileComponents();
});
it('starts at zero', () => {
const fixture = TestBed.createComponent(Counter);
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('0 x 2 = 0');
});
it('increments when the button is clicked', () => {
const fixture = TestBed.createComponent(Counter);
fixture.detectChanges();
const button: HTMLButtonElement = fixture.nativeElement.querySelector('button');
button.click();
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('1 x 2 = 2');
});
});fixture.detectChanges() runs change detection so the DOM reflects the latest state. When a component waits for asynchronous work, await fixture.whenStable() waits until pending tasks have finished.
To test a component in isolation, give it a fake version of a service through providers. Because inject() resolves through the same injector, the component receives the fake:
import { TestBed } from '@angular/core/testing';
import { signal } from '@angular/core';
import { HeroList } from './hero-list';
import { HeroService } from './hero.service';
it('renders heroes from the service', async () => {
const fakeService = { all: signal([{ id: 1, name: 'Test Hero' }]), add: () => {} };
await TestBed.configureTestingModule({
imports: [HeroList],
providers: [{ provide: HeroService, useValue: fakeService }],
}).compileComponents();
const fixture = TestBed.createComponent(HeroList);
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('Test Hero');
});provideHttpClientTesting() swaps the real backend for HttpTestingController, which lets a test inspect outgoing requests and answer them. Register it after provideHttpClient():
import { TestBed } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing';
import { Todo, TodoApi } from './todo-api';
describe('TodoApi', () => {
let api: TodoApi;
let http: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [provideHttpClient(), provideHttpClientTesting()],
});
api = TestBed.inject(TodoApi);
http = TestBed.inject(HttpTestingController);
});
afterEach(() => http.verify());
it('requests a limited list', () => {
let result: Todo[] = [];
api.list(2).subscribe((todos) => (result = todos));
const req = http.expectOne((r) => r.url.endsWith('/todos'));
expect(req.request.method).toBe('GET');
expect(req.request.params.get('_limit')).toBe('2');
req.flush([{ id: 1, title: 'Write tests', completed: false }]);
expect(result.length).toBe(1);
});
});http.verify() fails the test if any request was made but never answered.
New projects do not include an e2e framework. Running ng e2e in a project without an e2e target offers to add one; the choices include Playwright, Cypress, WebdriverIO, Nightwatch and Puppeteer. You can also install a tool directly. With Playwright:
npm init playwright@latest
npx playwright testPoint Playwright at the dev server in playwright.config.ts so it starts the app before the tests:
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: { baseURL: 'http://localhost:4200' },
webServer: {
command: 'npm start',
url: 'http://localhost:4200',
reuseExistingServer: !process.env['CI'],
},
});import { expect, test } from '@playwright/test';
test('home page greets the user', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('heading', { level: 1 })).toContainText('Hello');
});ng test runs .spec.ts files with the project's configured runner: Vitest in recent projects, Karma and Jasmine in older ones.TestBed creates components and services; detectChanges() updates the DOM.providers and test HTTP with provideHttpClientTesting().ng e2e or by installing it directly.
0 comentários
Fazer login · Faça login para deixar um comentário.
Seja o primeiro a comentar.