繁体   English   中英

Js文件作为cypress中的fixture未加载

[英]Js file as fixture in cypress not loaded

你如何使用 js 文件作为夹具? 这有什么例子吗? 我在 user-details.js 中试过这个:

data = {
  email: function () {
    const currentTimestamp = new Date().getTime();
    return `test${currentTimestamp}@test.com`
  },
  firstName: 'Max',
  lastName: 'Mustermann',
  street: 'Some Street',
} 

然后在我的规范文件中我这样做:

beforeEach(function () {
    cy.fixture(env + '/user-details').as('userDetails');
  }); 

在同一规范文件中的测试的it块中:

const userDetails = this.userDetails.data;
actions.insertStreet(userDetails.street);

但它说它无法读取未定义的属性“街道”。 任何想法如何正确地做到这一点? :sweat_smile:

柏树文档

加载位于文件中的一组固定数据。

您尝试加载的不是一组固定的数据。 它是一个包含动态函数的对象,该函数每次运行时返回的数据都是唯一的。 您正在尝试对绝对不是 json 的东西应用类似 json 的态度。 您需要将夹具视为真正的 api 调用将返回的东西 - JSON、图像、二进制文件等。api 调用可能不会像您的 user-details.js 文件那样返回原始文本/javascript 文件并期望前端知道如何处理它。

您的选择:

  1. 使其成为真正的 JSON,并为日期使用硬编码值
  2. 执行export data = { ... } ,然后将该值导入您的 .spec.js 文件并使用它
  3. 只需包含内联值,或在 .spec 文件的顶部创建一个函数来为您创建它们

抱歉,如果这不是您希望听到的

编辑:根据要求,这是选项 3 的示例:

// any.spec.js

function createUserDetails(){
  return {
    email: `test${new Date().getTime()}@test.com`,
    firstName: 'Max',
    lastName: 'Mustermann',
    street: 'Some Street',
  }
};

describe('your test block', => {

  it('tests some stuff', () => {
    const userDetails = createUserDetails();
    actions.insertStreet(userDetails.street);
  });

  it('tests some other stuff', () => {
    const userDetails = createUserDetails();
    actions.insertEmail(userDetails.email);
  });

});

因此,您可以在一个地方定义您的数据创建者,但可以在多个地方重用它。

我有同样的问题,并且无法将接受的答案与我看到的情况完全一致(在赛普拉斯 9.2.1 中)。

事实证明,当.js文件作为夹具给出时, cypress eval()是文件的内容(实际上,它使用eval-with-parentheses ),并使用由此产生的任何对象。所以可以有一个文件user-details.js ,看起来像

[{name: "Bob", age: 30 + 5}]

甚至执行一些“真实”代码:

["Bob", "Rob", "Job"].map((name, index) => ({user: name, age: 20 + index}))

或者

(() => {
    const users = ....
    return users
})()

应该注意的是,它并不像您想要的那样灵活(例如,您不能导入代码、执行异步操作等),但它不仅仅是没有。

问题是,你应该......

老实说,我认为这是一种很好的方法,可以让您的灯具易于阅读,能够添加评论和轻松转换。 而且你不会被 JSON 的逗号困扰。

[
  // have a single user, because blah blah
  {name: "Bob", date_of_birth: new Date(1979, 5, 3).valueOf() / 1000},
]

Date(1979, 5, 3)比某些 unix 时间戳更易于阅读(即使它表示 6 月 5 日,而不是 5 月 5 日......)

我完全认为.js夹具是做到这一点的好方法(如果它只是将夹具作为模块导入并使用默认导出作为项目或其他东西会更快乐,但eval是可以接受的......) ,只要你生产的东西是不变的 如果你想要一些动态的东西(或者,可能是一些需要更复杂的常量),你最好使用@seth-lutske 的建议(这意味着在你的情况下,接受的答案就是你需要的,但是我想记录下.js固定装置是如何工作的,以防其他人经过)。

说了这么多,即使建议的方法是使用window.Function() ,为什么 cypress 在这里使用eval()也是值得怀疑的; 另外,我想知道你是否想冒这样的风险,其他一些开发人员(包括未来的你)决定构建一个系统,从某个外部网站下载你的装置,这意味着你创造了一个很好的安全漏洞……

阅读关于 Javascript 固定装置的github 问题非常有用(我希望在我自己深入研究这一切之前就拥有); 如果您正在寻找一个好的解决方法,请参阅评论和评论。


作为对所提问题的具体回答,问题在于

eval(`data = {
  email: function () {
    const currentTimestamp = new Date().getTime();
    return \`test\${currentTimestamp}@test.com\`
  },
  firstName: 'Max',
  lastName: 'Mustermann',
  street: 'Some Street',
} `)

将准确返回该对象,该对象应该可以在this.userDetails上访问。 因此this.userDetails.data指向这个对象中的数据字段,它是undefined

以下将起作用:

用户详细信息.js:

{
  data: {
    email: function () {
      const currentTimestamp = new Date().getTime();
      return `test${currentTimestamp}@test.com`
    },
    firstName: 'Max',
    lastName: 'Mustermann',
    street: 'Some Street',
  }
} 

(或者,如果您希望email成为字符串而不是函数:

{
  data: {
    email: (function () {
      const currentTimestamp = new Date().getTime();
      return `test${currentTimestamp}@test.com`
    })(),
    firstName: 'Max',
    lastName: 'Mustermann',
    street: 'Some Street',
  }
} 

)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM