在赛普拉斯中如何对带有间谍的物体断言?

Bra*_*don 1 javascript sinon cypress

我正在使用赛普拉斯间谍来测试客户端分析。

我在此测试中的目的是确认identify已这样调用:

identify('myemail@email.com', { groupId: 1002, groupName: "myGroup", someProp: 1, anotherProp: 2 })

我将间谍挂接到全局analytics对象的发射器事件中window:before:load(请注意,while循环是为了处理库加载中的延迟):

Cypress.on("window:before:load", async (win: Window) => {

  const sleep = (n = 1) => new Promise(r => setTimeout(r, n));
  let set = false;
  while (set === false) {
    if (win["analytics"]) {
      set = true;
      const a = win["analytics"];
      const pageSpy = cy.spy().as("page");
      const idSpy = cy.spy().as("identify");
      a.on("page", pageSpy);
      a.on("identify", idSpy);

    } else {
       // default sleep of 1ms. this is b/c there's a super tight
       // window from analytics init and the calls I'm looking to
       // track (~25ms)
      await sleep();
      continue;
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

目的是每次调用a pageidentifymethod时,都使用page/ identify调用中的args 调用间谍。

然后,在我的测试中:

 it("calls identify on page load", () => {
    const idProps = {
      groupId: 1002,
      groupName: "myGroup",
      someProp: 1,
      anotherProp: 2
    };

    cy.visit("https://mypage.com");

    cy.get("@identify").should(
      "be.calledWith",
      "myemail@email.com"
    ).and("be.calledWith",idProps);
  });
Run Code Online (Sandbox Code Playgroud)

第一个断言通过("be.calledWith", "myemail@email.com")。

但是,第二个断言失败了:

Command:  get
cypress_runner.js:141344 Alias:    @identify
cypress_runner.js:141344 Yielded:  ƒ identify
cypress_runner.js:141344 Error:    CypressError: Timed out retrying: expected identify to have been called with arguments Object{4}

    The following calls were made:

    identify("myemail@email.com", Object{4}, undefined) at o.proxy (https://exmaple.com/__cypress/runner/cypress_runner.js:45839:22)
Run Code Online (Sandbox Code Playgroud)

我尝试使用sinon.match,但是Cypress版本的sinon不支持

我还尝试提取原始调用/参数(即spy.getCalls()),但是通过别名(即cy.get('@identify'))访问间谍时似乎不支持此功能。

那么:有什么方法可以使传递给柏树间谍的args深度匹配?

Bra*_*don 5

我已经解决了OP标题中的问题。将分析方法包装为间谍是另一个问题,但我已经更新了OP中的代码段以反映我如何解决该问题(即,将睡眠间隔更改为1ms)。

您可以使用的回调签名在间谍调用的args中声明该对象cy.should

 const idProps = {
      groupId: 1002,
      groupName: "myGroup",
      someProp: 1,
      anotherProp: 2
    };

cy.get("@identify").should(a => {
      expect(a).to.be.calledWith("myemail@email.com");
      // pardon the property index-ref style, using typescript and i'm lazy
      const spy = a["getCalls"](); 
      const { args } = spy[0];
      expect(args[1]).to.deep.equal(idProps);
    });
Run Code Online (Sandbox Code Playgroud)