Is there a way to assert that a route has not been called in Cypress?

走远了吗. 提交于 2021-01-02 05:04:08

问题


I am trying to assert that a route has not been called in Cypress. I thoroughly looked through the documentation and have found nothing.

I am trying to do something like this:

cy.get('@myRouteAlias').should('have.not.been.called');

I am currently working around this by asserting that the successful request toast message is not being displayed but it is a flimsy solution.

Any ideas?


回答1:


It is very difficult to test a situation where an action has not occured. With this type of assertion, you can really only say:

"The XHR request was not made within the 400ms that Cypress looked for this XHR request to have been made (or whatever you set your timeout to be)"

This doesn't really confirm that the XHR request was never called.

That being said, Cypress offers a way to retrieve all XHR requests made using the undocumented cy.state('requests'). You could check the length of that, filter them by alias, etc to probably determine what you want.




回答2:


Unfortunately none of the above really worked for me, I got it working with this command :

Cypress.Commands.add('shouldBeCalled', (alias, timesCalled) => {
  expect(
    cy.state('requests').filter(call => call.alias === alias),
    `${alias} should have been called ${timesCalled} times`
  ).to.have.length(timesCalled);
});

Which I then use like this :

// Checks that FetchChatList has not been called
cy.shouldBeCalled('FetchChatList', 0);



回答3:


As a variant set in routes options onResponse function which drops test

e.g. expect(true).to.be.false;

it will fire error if call happened for current route

cy.route({
    url: <url>,
    onResponse: function () {
       expect("Unexpected Https call").to.be.false;
    }
})



回答4:


It is worth considering the asynchronous nature of this test, something the previous examples have not taken into account. Here is a working example:

cy.route('/my-route').as('myRoute')

const noExpectedCalls = 1

cy.get('@myRoute').then(() => {
  expect(cy.state('requests').filter(r => r.alias === 'myRoute')).to.have.length(noExpectedCalls)
})



回答5:


To simplify @Jennifer Shehane's great answer:

let requestsCount = (alias) => cy.state('requests').filter(a => a.alias === alias).length;

expect(requestsCount('putRequest')).to.eq(0);

And you could put it in your Cypress commands file, too!




回答6:


I tried the simplified version that Jonathan posted, but am seeing TypeError: Cannot read property 'filter' of undefined and cy.state('requests') is always undefined.




回答7:


Here is the correct way to assert requests count using cypress's commands.

Put this in your commands.js file:

Cypress.Commands.add('requestsCount', (alias) =>
  cy
    .wrap()
    .then(() => cy.state('requests').filter(req => req.alias === alias).length),
);

Than in your tests use a new command as follows:

it('should count requests', () => {
  cy.server();
  cy.route('**').alias('theRequest');

  cy.wait('@theRequest');
  cy.requestsCount('theRequest').should('eq', 1);
});



回答8:


This is how the cypress team does it (source):

it("throws when alias is never requested", (done) => {
  Cypress.config("requestTimeout", 100);

  cy.on("fail", (err) => {
    expect(err.message).to.include(
      "`cy.wait()` timed out waiting `100ms` for the 1st request to the route: `foo`. No request ever occurred."
    );

    done();
  });

  cy.server().route(/foo/, {}).as("foo").wait("@foo.request");
});

And from the related docs:

Fires when the test has failed. It is technically possible to prevent the test from actually failing by binding to this event and invoking an async done callback. However this is strongly discouraged. Tests should never legitimately fail. This event exists because it’s extremely useful for debugging purposes




回答9:


cy.state seems to be undefined when 0.

Also, if you want to call the command with the @, then this will work.

Cypress.Commands.add('shouldBeCalled', (alias, timesCalled) => {
  const aliasname = alias.substring(1);
  const requests = cy.state('requests') || [];

  expect(
    requests.filter((call) => call.alias === aliasname),
    `${aliasname} should have been called ${timesCalled} times`
  ).to.have.length(timesCalled);
});

cy.shouldBeCalled('@updateCalc', 1);


来源:https://stackoverflow.com/questions/47354360/is-there-a-way-to-assert-that-a-route-has-not-been-called-in-cypress

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!