如何在无后端情况下分步测试Angular前端
Angular前端无后端时的分步开发与测试方案
一、模拟登录接口生成JWT
创建LoginMockInterceptor拦截登录请求,替代真实后端返回模拟JWT:
- 编写拦截器代码:
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { Observable, of } from 'rxjs'; import { delay } from 'rxjs/operators'; @Injectable() export class LoginMockInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // 匹配登录接口路径(示例为/api/auth/login) if (req.url.includes('/api/auth/login') && req.method === 'POST') { const { email, password } = req.body; // 自定义简单验证规则 const isValid = email === 'test@example.com' && password === '123456'; if (isValid) { // 用jwt.io生成的测试JWT const mockToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAZXhhbXBsZS5jb20iLCJleHAiOjE3MTk5OTk5OTl9.SW9fX7Z8kQZ8aQZ8kQZ8aQZ8kQZ8aQZ8kQZ8aQZ8'; // 模拟网络延迟后返回成功响应 return of({ success: true, token: mockToken, user: { email, name: 'Test User' } }).pipe(delay(500)); } else { // 返回登录失败响应 return of({ success: false, message: '邮箱或密码错误' }).pipe(delay(500)); } } // 非登录请求继续走原流程 return next.handle(req); } }
- 在
app.module.ts注册拦截器:
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { LoginMockInterceptor } from './login-mock.interceptor'; @NgModule({ providers: [ { provide: HTTP_INTERCEPTORS, useClass: LoginMockInterceptor, multi: true } ] }) export class AppModule { }
登录组件中需补充token存储逻辑,在AuthService添加:
setToken(token: string): void { localStorage.setItem(this.tokenKey, token); }
登录成功时调用:
login(email: string, password: string) { this.http.post('/api/auth/login', { email, password }).subscribe({ next: (res: any) => { if (res.success) { this.authService.setToken(res.token); // 跳转首页等后续操作 } } }); }
二、确保现有AuthInterceptor正常工作
你已有的AuthInterceptor无需修改——只要模拟登录成功后token被存入localStorage,后续所有请求都会自动带上Authorization: Bearer {token}请求头,完全适配模拟环境。
三、模拟后端接口与内存数据存储
根据技术栈选择以下两种方案:
方案1:Angular In-Memory Web API(REST场景)
适合RESTful接口模拟,自带内存数据库:
- 安装依赖:
npm install angular-in-memory-web-api --save-dev
- 创建内存数据服务:
import { Injectable } from '@angular/core'; import { InMemoryDbService } from 'angular-in-memory-web-api'; @Injectable({ providedIn: 'root' }) export class InMemoryDataService implements InMemoryDbService { createDb() { // 定义模拟业务数据 const users = [ { id: 1, email: 'test@example.com', name: 'Test User' }, { id: 2, email: 'user@example.com', name: 'Normal User' } ]; const products = [ { id: 1, name: 'Product A', price: 99 }, { id: 2, name: 'Product B', price: 199 } ]; return { users, products }; } }
- 在
app.module.ts配置启用:
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api'; import { InMemoryDataService } from './in-memory-data.service'; @NgModule({ imports: [ HttpClientModule, HttpClientInMemoryWebApiModule.forRoot( InMemoryDataService, { delay: 500, passThruUnknownUrl: true } // passThruUnknownUrl允许非模拟请求通过 ) ] }) export class AppModule { }
之后GET /api/users、POST /api/products等请求会自动被拦截,从内存数据库读写数据,完全模拟真实后端行为。
方案2:Apollo Client本地状态(GraphQL场景)
适配GraphQL技术栈,用Apollo管理本地数据并模拟查询/突变:
- 配置Apollo Client本地状态:
import { ApolloClient, InMemoryCache, gql } from '@apollo/client/core'; // 定义本地查询 const GET_USERS = gql` query GetUsers { users @client { id email name } } `; // 初始化内存缓存数据 const cache = new InMemoryCache({ typePolicies: { Query: { fields: { users: { read() { return [ { id: 1, email: 'test@example.com', name: 'Test User' }, { id: 2, email: 'user@example.com', name: 'Normal User' } ]; } } } } } }); // 创建Apollo Client实例 export const apolloClient = new ApolloClient({ cache, uri: 'http://localhost:4000/graphql', // 真实后端地址,本地查询自动忽略 });
- 组件中查询本地数据:
this.apollo.watchQuery({ query: GET_USERS }).valueChanges.subscribe(res => { this.users = res.data.users; });
可额外定义本地突变逻辑,模拟数据修改类请求的行为。
内容的提问来源于stack exchange,提问作者Volia
相关产品推荐
相关产品推荐

