使用截取更改同一 url 的 cypress 中的夹具响应

Sas*_*ick 9 testing angular cypress

我正在尝试使用新的 cypress 6 拦截器方法(Cypress API Intercept)编写测试。对于我正在编写的测试,我需要在执行某些操作后更改一个端点的响应。

期待:

我用另一个装置再次调用 cy.intercept 并期望它改变所有即将到来的调用以响应这个新装置。

实际行为:

赛普拉斯仍然使用为呼叫设置的第一个夹具来响应。

测试数据:

在一个测试项目中,我重新创建了这个问题:

测试规范.js

describe('testing cypress', () => {


    it("multiple responses", () => {

        cy.intercept('http://localhost:4200/testcall', { fixture: 'example.json' });

        // when visiting the page it makes one request to http://localhost:4200/testcall
        cy.visit('http://localhost:4200');
        cy.get('.output').should('contain.text', '111');

        // now before the button is clicked and the call is made again
        // cypress should change the response to the other fixture
        cy.intercept('http://localhost:4200/testcall', { fixture: 'example2.json' });

        cy.get('.button').click();
        cy.get('.output').should('contain.text', '222');
        
    });

});
Run Code Online (Sandbox Code Playgroud)

例子.json

{
  "text": "111"
}
Run Code Online (Sandbox Code Playgroud)

示例2.json

{
  "text": "222"
}
Run Code Online (Sandbox Code Playgroud)

app.component.ts

import { HttpClient } from '@angular/common/http';
import { AfterViewInit, Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {

  public text: string;

  public constructor(private httpClient: HttpClient) { }

  public ngAfterViewInit(): void {
    this.loadData();
  }

  public loadData(): void {
    const loadDataSubscription = this.httpClient.get<any>('http://localhost:4200/testcall').subscribe(response => {
      this.text = response.body;
      loadDataSubscription.unsubscribe();
    });
  }

}
Run Code Online (Sandbox Code Playgroud)

应用程序组件.html

<button class="button" (click)="loadData()">click</button>

<p class="output" [innerHTML]="text"></p>
Run Code Online (Sandbox Code Playgroud)

Pao*_*olo 18

自 2021 年 4 月 5 日发布的 Cypress v7.0.0起,cy.intercept()允许覆盖。

我们对 cy.intercept() 引入了几项重大更改。

  • 提供给 cy.intercept() 的请求处理程序现在从最近定义的请求拦截器开始匹配。这允许用户通过再次调用 cy.intercept() 来覆盖请求处理程序。

所以上面的示例代码现在可以工作了

cy.intercept('http://localhost:4200/testcall', { fixture: 'example.json' });

// when visiting the page it makes one request to http://localhost:4200/testcall
cy.visit('http://localhost:4200');
cy.get('.output').should('contain.text', '111');

// now cypress should change the response to the other fixture
cy.intercept('http://localhost:4200/testcall', { fixture: 'example2.json' });

cy.get('.button').click();
cy.get('.output').should('contain.text', '222');
Run Code Online (Sandbox Code Playgroud)


Ric*_*sen 11

有点笨拙,但您可以将一个cy.intercept()Function routeHandler 一起使用,并计算调用次数。

就像是,

let interceptCount = 0;  

cy.intercept('http://localhost:4200/testcall', (req) => {   
  req.reply(res => {     
    if (interceptCount === 0 ) {
      interceptCount += 1;
      res.send({ fixture: 'example.json' })
    } else {
      res.send({ fixture: 'example2.json' })
    }
  }); 
});
Run Code Online (Sandbox Code Playgroud)

否则,您的代码中的一切看起来都不错,所以我猜此时覆盖拦截不是一项功能。

  • 在花了几个小时尝试OP想要的同样的东西之后,我最终也使用了这种笨拙的方式。谢谢你的建议。 (3认同)

小智 11

Cypress 命令cy.intercept具有 times可用于创建仅使用 N 次的拦截的参数。在你的情况下它会是

cy.intercept('http://localhost:4200/testcall', { 
  fixture: 'example.json',
  times: 1 
});
...
cy.intercept('http://localhost:4200/testcall', { 
  fixture: 'example2.json',
  times: 1
});
Run Code Online (Sandbox Code Playgroud)

请参阅cy.interceptCypress 食谱存储库中的示例https://github.com/cypress-io/cypress-example-recipes#network-stubbing-and-spying