首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

测试angular http拦截器-在intercept返回之前调用expect

在Angular中,HTTP拦截器是一种特殊的服务,它允许你在HTTP请求发送到服务器之前或响应从服务器返回之后对其进行修改。拦截器通常用于添加认证头、处理错误、重定向等。

基础概念

HTTP拦截器实现了HttpInterceptor接口,该接口定义了一个intercept方法。这个方法接收两个参数:一个是HttpRequest对象,另一个是HttpHandler对象。HttpHandler是一个函数,它接收一个HttpRequest并返回一个Observable<HttpEvent<any>>

相关优势

  1. 统一处理请求和响应:可以在一个地方集中处理所有的HTTP请求和响应。
  2. 添加通用逻辑:比如添加认证令牌、错误处理、日志记录等。
  3. 重试机制:可以在拦截器中实现请求失败后的自动重试逻辑。
  4. 请求取消:可以在某些条件下取消正在进行的HTTP请求。

类型

  • 请求拦截器:在请求发送到服务器之前对其进行修改。
  • 响应拦截器:在响应从服务器返回之后对其进行处理。

应用场景

  • 认证:在每个请求中添加认证令牌。
  • 错误处理:统一处理HTTP错误,如401未授权、500服务器错误等。
  • 日志记录:记录请求和响应的详细信息。
  • 请求重试:在请求失败时自动重试。

示例代码

下面是一个简单的HTTP拦截器示例,它在每个请求中添加一个认证令牌,并在响应返回之前打印日志。

代码语言:txt
复制
import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // 克隆请求并在头部添加认证令牌
    const authReq = req.clone({
      headers: req.headers.set('Authorization', 'Bearer your-auth-token')
    });

    // 打印请求信息
    console.log('Request:', authReq);

    // 发送请求并监听响应
    return next.handle(authReq).pipe(
      tap(event => {
        if (event instanceof HttpResponse) {
          // 打印响应信息
          console.log('Response:', event);
        }
      }, error => {
        // 处理错误
        console.error('Error:', error);
      })
    );
  }
}

遇到的问题及解决方法

如果你在测试HTTP拦截器时遇到了问题,比如在intercept方法返回之前调用expect失败,可能是因为你没有正确地订阅拦截器返回的Observable

问题原因Observable是异步的,如果你没有订阅它,那么expect可能会在拦截器完成工作之前执行。

解决方法:确保你在测试中订阅了拦截器返回的Observable

代码语言:txt
复制
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';

describe('AuthInterceptor', () => {
  let httpMock: HttpTestingController;
  let httpClient: HttpClient;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [AuthInterceptor]
    });

    httpMock = TestBed.inject(HttpTestingController);
    httpClient = TestBed.inject(HttpClient);
  });

  afterEach(() => {
    httpMock.verify();
  });

  it('should add authorization header', () => {
    httpClient.get('/api/data').subscribe(response => {
      expect(response).toBeTruthy();
    });

    const req = httpMock.expectOne('/api/data');
    expect(req.request.headers.has('Authorization')).toBeTruthy();
    req.flush({});
  });
});

在这个测试示例中,我们使用HttpClientTestingModule来模拟HTTP请求,并通过HttpTestingController来验证请求是否按预期进行。我们订阅了httpClient.get的调用结果,以确保在断言之前拦截器有机会修改请求。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Angular HttpClient 拦截器

在之前的 Angular 6 HttpClient 快速入门 文章中,我们已经简单介绍了 Http 拦截器。本文将会进一步分析一下 Http 拦截器。拦截器提供了一种用于拦截、修改请求和响应的机制。...CachingInterceptor 在实现缓存拦截器之前,我们先来定义一个 Cache 接口: import { HttpRequest, HttpResponse } from '@angular/...Testing 为了方便演示 AuthInterceptor 拦截器的单元测试,首先我们先来定义一个 UserService 类: import { Injectable } from "@angular..." ); }); }); 在完成 spec 文件的定义之后,我们就可以运行 npm run test 或 ng test 命令,运行单元测试了。...这里只是简单介绍了如何为 AuthInterceptor 拦截器写单元测试,对于单元测试的同学,建议阅读官方或其他的学习资料。

2.6K20

Angular 从入坑到挖坑 - HTTP 请求概览

在使用之前,首先需要在应用的根模块中,引入 HttpClientModule 模块,并添加到 imports 数组中 import { BrowserModule } from '@angular/platform-browser...通过使用 postman 进行接口调用可以发现,接口返回的响应信息如下 ?...(url); } } 在组件中,通过调用注入的服务类完成接口数据的获取,因为是以一种结构化对象的形式获取到接口返回的数据,因此这里可以直接通过对象属性获取到指定的属性信息...根据 postman 的调用示例,在服务中定义一个方法用来提交毒鸡汤信息,这里的 SetQuotesResponseModel 为接口返回的响应对象 import { Injectable } from...,从而不需要在后续的业务逻辑代码中再进行判断请求是否成功 4.3.1、自定义拦截器 在 Angular 中可以新建一个继承于 HttpInterceptor 接口的拦截器类,通过实现 intercept

5.3K10
  • OkHttp源码解析

    关于拦截器,之前在 一起来写OKHttp的拦截器 这篇博客中有讲过,若不了解的同学可以先看下。 我们都知道,拦截器是 OkHttp 的精髓。...; CallServerInterceptor 是真正向服务器发出请求且得到响应的拦截器; 最后在聚合了这些拦截器后,利用 RealInterceptorChain 来链式调用这些拦截器,利用的就是责任链模式..."interceptor " + interceptor + " returned a response with no body"); } return response; } 在代码中是一次次链式调用拦截器...下面就要进入分析拦截器的步骤了,至于用户自定义的拦截器在这就略过了。还有,拦截器只分析主要的 intercept(Chain chain) 代码。...= null) { // If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1

    76430

    OkHttp3.0 拦截器、调度器源码解析

    forWebSocket 变量在非 Socket请求时为false,也就是说长连接是不会添加网络拦截器的,代码接着往下走,咱们查看 RealInterceptorChain 构造方法 public RealInterceptorChain...(next) 方法,OkHttp 的拦截器采用的是责任链设计模式,原理就是符合规则依次调用,这里的规则就是当前的拦截器将下一个拦截器通过intercept()方法传递,然后与此同时 index + 1,...我们依次点开这些拦截器的 intercept 做了什么,还记得之前咱们看的拦截器添加顺序吗,代码进入RetryAndFollowUpInterceptor拦截器的intercept ()方法 @Override...RealInterceptorChain,实际上,咱们又再一次调用了proceed()方法,接下来相信大家都能理解了,遍历整个队列直到最后一个访问服务器拦截器,咱们点进CallServerInterceptor...= null) { // If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100

    89220

    Angular2 之 单元测试

    在每个spec之前 ,TestBed将自己重设为初始状态。...detectChanges:在测试中的Angular变化检测。 每个测试程序都通过调用fixture.detectChanges() 来通知Angular执行变化检测。...比如,它不返回承诺,并且没有done方法可调用,因为它是标准的Jasmine异步测试程序。...和async一样,它也接受无参数函数并返回一个函数,变成Jasmine的it 函数的参数。 fakeAsync函数通过在特殊的fakeAsync测试区域运行测试程序,让测试代码更加简单直观。...---- 多次调用同一个异步方法 相信大家对这段单元测试的代码很熟悉,这里就是模拟多次调用同一个方法时,返回不同的值。 这里是同步方法的模拟返回数据,那么异步方法同样可以。

    5.5K20

    开源框架源码解析系列(1)——进入OkHttp的世界

    3.拦截器解析 3.1 拦截器执行顺序 在之前分析同步和异步任务的时候,分析过getResponseWithInterceptorChain()方法执行后就会返回请求结果Response Response...,执行下一个拦截器的逻辑 **总结一下:**这里责任链模式,每一个拦截器执行时都会创建一个拦截器链RealInterceptorChain,index也会随之增加1,这样在 interceptors.get...(index)中就会取出下一个拦截器,一直向下执行到没有拦截器为止,同时每一个拦截的Response是下一个拦截器执行的返回的结果 RetryAndFollowUpInterceptor最重要的是创建了...=null,那就调用接下来的拦截器进行请求,返回Response if (cacheResponse !...= null) { // If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100

    59220

    一文彻底搞懂OkHttp

    ,这里用到了责任链模式,处理完拦截器列表后,会创建拦截器责任链,拦截器会按顺序依次调用,处理完成之后,再将返回信息返回给用户。...,然后复制并创建新的责任链 获取当前下标的拦截器 调用当前拦截器的intercept方法,并传入下一个拦截器责任链实例 为什么可以链式调用下去呢?...调用了chain.proceed方法返回Response,将逻辑交由下一个拦截器处理。...同时这个拦截器还会读取Cookie配置,如果有Cookie信息,也会通过请求头带到服务端。 在Request信息完善后,会调用后续的责任链去处理完善的Request,并等待后续的返回。...proceed方法会调用各个拦截器的intercept方法,拦截器在处理完成自己的职责后,继续调用proceed方法。

    1.8K10

    OkHttp源码流程分析

    [index] @Suppress("USELESS_ELVIS") //这里会调用拦截器的方法 接下来我们会分析各个拦截器的作用 val response = interceptor.intercept...其实就是遍历调用各拦截器 对Request进行作用 直到return response 我们来逐个分析一下各个拦截器的作用 本文只分析处理Request,response的处理会在下文讲解 RetryAndFollowUpInterceptor...而是直接原路返回 return response ConnectInterceptor 作用:负责与服务器连接 这个拦截器的过程分析其实相当复杂undefined 简单来说流程是从连接池中查找连接 如果不存在...在阅读CallServerInterceptor之前 我们有必要看一下Http2.0相关知识 因为在CallServerInterceptor中会根据不同的Http协议 使用不同的传输方式 我们看一下...支持明文和加密传输,优化header压缩算法,支持SPDY现有功能,全双工 Quic基于UDP实现稳定传输协议 弱网有优化 CallServerInterceptor 作用:负责与服务器进行数据交互 在了解和服务器交互的流程之前

    46850

    OkHttp源码走心解析(很细 很长)

    ,最终会执行拦截器列表中的每个拦截器,返回Response。...先上各类拦截器的总结,按顺序: client.interceptors:这是由开发者设置的,会在所有的拦截器处理之前进行最早的拦截处理,可用于添加一些公共参数,如自定义header、自定义log等等。...= "GET" ) //根据连接,创建并返回一个请求响应编码器:Http1ExchangeCodec 或者 Http2ExchangeCodec,分别对应Http1协议与Http2...而网络拦截器处于倒数第二的位置,它不一定会被执行,而且可能会被执行多次,比如:在RetryAndFollowUpInterceptor失败或者CacheInterceptor直接返回缓存的情况下,我们的网络拦截器是不会被执行的...= null) { //当请求头为"Expect: 100-continue"时,在发送请求体之前需要等待服务器返回"HTTP/1.1 100 Continue" 的response,如果没有等到该

    1.1K41

    Angular 中的请求拦截

    在上一篇的文章 Angular 中使用 Api 代理,我们处理了本地联调接口的问题,使用了代理。 我们的接口是单独编写的处理的,在实际的开发项目中,有众多的接口,有些需要登陆凭证,有些不需要。...在使用 angular-cli 生成项目的时候,它已经自动做好了环境的区分,在 app/enviroments 目录下: environments...当然,你这里添加的内容要配合你代理上加的内容调整,读者可以自己思考验证 添加拦截器 我们生成服务 http-interceptor.service.ts 拦截器服务,我们希望每个请求,都经过这个服务..., HttpInterceptor, // 拦截器 HttpRequest, // 请求 } from '@angular/common/http'; import { Observable...,我们还得在 app.module.ts 上注入: // app.module.ts import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular

    2.4K20

    深入理解OkHttp源码(二)——获取响应

    因为一开始httpStream为null,所以前面的判断都无效,直接进入第92行,首先创建next拦截器链,主需要把索引置为index+1即可;然后获取第一个拦截器,调用其intercept方法。...=null: 缓存响应之前存在,如果之前的缓存还有效的话,那么需要更新缓存,返回组合后的响应 2)cacheResponse==null: 之前没有缓存响应,则将组合后的响应直接写入缓存即可。...在处理完网络拦截器后,会调用最后一个拦截器CallServerInterceptor。...在上面的代码分析中,应用拦截器是位于RetryAndFollowUpInterceptor之前,即拦截器链的最前端;网络拦截器位于CallServerInterceptor之前,即正在进行网络之前。...在CallServerInterceptor得到响应后,首先会交给网络拦截器处理响应,自然可以处理中间状态的响应。 不调用缓存响应,短路网络操作。

    65530

    【Hybrid开发高级系列】AngularJS(二)——常用$服务

    使用拦截器之前,我们通过factory()声明一个服务,然后通过$httpProvider注册拦截器。...拦截器允许你: 通过实现 request 方法拦截请求:         该方法会在 http 发送请求道后台之前执行,因此你可以修改配置或做其他的操作。...如果返回无效的响应对象或者 promise 会被拒绝,导致 http 调用失败。 通过实现 requestError 方法拦截请求异常:         有时候一个请求发送失败或者被拦截器拒绝了。...请求异常拦截器会俘获那些被上一个请求拦截器中断的请求。它可以用来恢复请求或者有时可以用来撤销请求之前所做的配置,比如说关闭进度条,激活按钮和输入框什么之类的。...对象,我们可以在响应返回时用then方法来处理回调。

    45440

    Spring RestTemplate进阶:拦截器

    这个接口的intercept(HttpRequest, byte[], ClientHttpRequestExecution)方法将通过让我们访问request、body和execution对象来拦截指定的请求并返回响应...,并且一旦执行完成,在返回前,这个拦截器将向每个响应添加一个自定义的HTTP头Foo。...测试 下面是测试RestTemplate拦截器的JUnit测试用例: public class RestTemplateItegrationTest { @Autowired RestTemplate...这个测试服务器将返回我们的请求体以及一些元数据。 6. 总结 本教程介绍如何设置拦截器并将其配置到RestTemplate对象中。这种拦截器还可以用于过滤、监控和控制传入的请求。...RestTemplate拦截器的一个常用场景是修改HTTP头——我们已经在本文中详细说明了这一点。 和往常一样,文中用到的示例代码可以在Github项目上找到。

    3K20
    领券