我试图断言赛普拉斯没有调用过一条路线。我仔细查看了文档并找不到任何内容。
我正在尝试做这样的事情:
cy.get('@myRouteAlias').should('have.not.been.called');
我目前正在解决这个问题,声称成功的请求toast消息没有显示,但它是一个脆弱的解决方案。
有什么想法吗?
答案 0 :(得分:11)
不幸的是,以上方法都不适合我,我可以使用以下命令来实现它:
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);
});
然后我这样使用:
// Checks that FetchChatList has not been called
cy.shouldBeCalled('FetchChatList', 0);
答案 1 :(得分:8)
很难测试某个操作不的情况。有了这种断言,你真的只能说:
“XHR请求未在赛普拉斯寻找此XHR请求的400ms
范围内(或您设置超时的任何内容)”
这确实确认XHR请求从未被调用。
话虽如此,赛普拉斯提供了一种方法来检索使用未记录的cy.state('requests')
发出的所有XHR请求。您可以检查其长度,通过别名等过滤它们,以确定您想要的内容。
答案 2 :(得分:5)
作为路由选项onResponse
功能的变体集,该功能将放弃测试
例如expect(true).to.be.false;
如果当前路线发生呼叫,则会触发错误
cy.route({
url: <url>,
onResponse: function () {
expect("Unexpected Https call").to.be.false;
}
})
答案 3 :(得分:2)
这是使用赛普拉斯的命令声明请求计数的正确方法。
将其放入您的commands.js
文件中:
Cypress.Commands.add('requestsCount', (alias) =>
cy
.wrap()
.then(() => cy.state('requests').filter(req => req.alias === alias).length),
);
在测试中使用的命令如下:
it('should count requests', () => {
cy.server();
cy.route('**').alias('theRequest');
cy.wait('@theRequest');
cy.requestsCount('theRequest').should('eq', 1);
});
答案 4 :(得分:2)
在 cy.intercept()
弃用后更新 cy.route()
。
如果您使用的是 cy.intercept()
,cy.state('requests')
将返回带有未定义 alias
的对象,因此我使用了 xhr.url
。
我这样调整@SleepWalker 的解决方案:
commands.js 文件中的命令:
Cypress.Commands.add('requestsCountByUrl', url =>
cy.wrap().then(() => {
const requests = cy.state('requests') || [];
return requests.filter(req => req.xhr.url === url).length;
})
);
测试中的使用:
cy.requestsCountByUrl('http://theUrl.com').should('eq', 1);
答案 5 :(得分:0)
为简化@Jennifer Shehane的好答案:
let requestsCount = (alias) => cy.state('requests').filter(a => a.alias === alias).length;
expect(requestsCount('putRequest')).to.eq(0);
您也可以将其放入赛普拉斯命令文件中!
答案 6 :(得分:0)
值得考虑此测试的异步特性,而前面的示例并未考虑到这一点。这是一个工作示例:
cy.route('/my-route').as('myRoute')
const noExpectedCalls = 1
cy.get('@myRoute').then(() => {
expect(cy.state('requests').filter(r = r.alias === 'myRoute').length).to.eq(noExpectedCalls)
})
答案 7 :(得分:0)
这是柏树小组的工作方式(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");
});
并从相关的docs:
在测试失败时触发。通过绑定到此事件并调用异步完成的回调,可以从技术上防止测试实际失败。但是,强烈建议不要这样做。测试永远不会合法失败。发生此事件是因为它对于调试非常有用
答案 8 :(得分:0)
select u.username,count(*) as total_booking,
count(case when status='Active' then 1 end) as active_bookings
from users u join bookings b on u.username=b.username
group by u.username
似乎为0时未定义。
此外,如果您想使用cy.state
调用该命令,那么它将起作用。
@
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);
});
答案 9 :(得分:0)
我想我找到了一种符合我预期的方法,即使用 cy.intercept
和 cy.state
。
cy.intercept
进行嗅探的路由cy.state('routes')
中。it(`should NOT make foo request`, () => {
// listen for any request with "foo" using cy.intercept
// I like to return success just to not see warnings in the console...
cy.intercept(/.foo./, { success: true }).as("fooRequest");
cy.window().then(win => {
// do what ever logic could make the request
makeFooRequestOrSomething();
});
// use cy.wait to wiat whatever amount of time you trust that your logoc should have run
cy.wait(1000);
/*
* cy.intercept does not provide any information unless a request is made, so instead
* we can use the state and make sure our route is not in the list
*/
let routes = cy.state('routes'); // An object representing all the routes setup via cy.intercept
let fooRoutes = [];
for (let route in routes) {
// routes[route].requests is an object representing each request
for (let req in routes[route].requests) {
let reqUrl = routes[route].requests[req].request.url;
// test each URL for "foo" and if it has it, add the URL to the array
if((/foo/).test(reqUrl)) {
fooRoutes.push(reqUrl);
}
}
};
// if no request was made to our URL, our array should be empty
expect(fooRoutes).to.have.property("length", 0);
});
routes[route]
可能在某个地方有 alias
,如果您想以不同的方式过滤数据,然后查看 routes[route].requests
是否为空。cy.state
方法。答案 10 :(得分:0)
当我们有路线时:
cy.intercept('PUT', '**/shoes/*', body).as('updateShoes');
以下解决方案对我有用:
cy.get('@updateShoes').then((interception) => {
assert.isNull(interception)
});
赛普拉斯说: 预期 null 等于 null
当 '@updateShoes' 路由被调用时(拦截)是一个对象:
{id: "interceptedRequest551", routeId: "1623772693273-2831", request: {…}, state: "Complete", requestWaited: false, …}
id: "interceptedRequest551"
log: {get: ƒ, unset: ƒ, invoke: ƒ, toJSON: ƒ, set: ƒ, …}
request: {headers: {…}, url: "http://localhost:8080/api/shoes/38de4e08", method: "PUT", httpVersion: "1.1", body: {…}}
requestWaited: false
response: {headers: {…}, body: {…}, url: "http://localhost:8080/api/shoes/38de4e08", method: null, httpVersion: null, …}
responseWaited: false
routeId: "1623772693273-2831"
state: "Complete"
subscriptions: []
...}
然后 Cypress 抛出一个错误:
AssertionError
expected { Object (id, routeId, ...) } to equal null
答案 11 :(得分:0)
这些在 7.6 版本中都不适合我,但我找到了一个非常简单的解决方案。
假设你有这样的拦截:
cy.intercept('GET', '**/foo/bar**').as('myRequest');
现在你可以这样做:
cy.wait(2000);
cy.get('@myRequest.all').then((interceptions) => {
expect(interceptions).to.have.length(0);
});
所以你等待一段时间,当请求可能发生时,并确保在等待之后它没有发生。对我来说效果很好,不需要额外的命令。 我在这里找到了解决方案:https://www.gitmemory.com/issue/cypress-io/cypress/15036/780706160
答案 12 :(得分:-1)
我尝试了乔纳森(Jonathan)发布的简化版本,但看到TypeError:无法读取未定义的属性'filter',而cy.state('requests')始终未定义。