Jest - 在describe块中导入多个测试,重用beforeEach()中定义的变量

Cyr*_*ris 11 javascript automated-tests jestjs

我熟悉RSpec,通过编写共享示例很容易重用测试用例

shared_example_for 'a cute pet' do 
  it 'tests that the pet is a small' { expect(pet.size).to be_lesser_than(10) }
  it 'tests that the pet can smile' { expect(pet.can_smile?).to be }
end

describe 'The Octocat' do
  let(:pet) Octocat.new

  it_behaves_like 'a cute pet'
end
...
describe 'The Doge' do 
  let(:pet) Doge.new

  it_behaves_like 'a cute pet'
end
Run Code Online (Sandbox Code Playgroud)

在Jest中有相同的东西吗?有什么能让我重用在beforeEach()块中设置的变量?我试图找到一种方法,使用类似如下的方法:

# __tests__/cuteness.js
export const cutenessTests = function() {
  test('it is small', () => {
    expect(petSetInBefore.length).toBeLesserThan(5)
  })
  test('it can smile', () => {
    expect(petSetInBefore.canSmile).toBe(true)
  })
}

# __tests__/famous_animals.test.js
import { cutenessTests } from './cuteness'

describe('Famous animals', () => {
  let petSetInBefore;

  describe('Octocat', () => {
    beforeEach(() => {
      petSetInBefore = new Octocat();
    })

    cutenessTests.bind(this)()
  })
})

Run Code Online (Sandbox Code Playgroud)

这里重要的是我试图共享多个test定义,而不只是一个,否则我可以将petSetInBefore传递给共享函数

tim*_*tgl 6

You can simply move the shared tests into a function that does the it() calls.

\n\n
class Octocat {\n  get length() {\n    return 3;\n  }\n\n  get canSmile() {\n    return true;\n  }\n}\n\nclass GrumpyCat {\n  get length() {\n    return 1;\n  }\n\n  get canSmile() {\n    return false;\n  }\n}\n\nconst behavesLikeAPet = (pet) => {\n  it('is small', () => expect(pet.length).toBeLessThan(5));\n  it('can smile', () => expect(pet.canSmile).toEqual(true));\n};\n\ndescribe('Famous animals', () => {\n  describe('Octocat', () => {\n    behavesLikeAPet(new Octocat());\n  });\n\n  describe('GrumpyCat', () => {\n    behavesLikeAPet(new GrumpyCat());\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

您将获得每个测试的详细输出:

\n\n
Famous animals\n  Octocat\n    \xe2\x9c\x93 is small (2ms)\n    \xe2\x9c\x93 can smile (1ms)\n  GrumpyCat\n    \xe2\x9c\x93 is small\n    \xe2\x9c\x95 can smile (2ms)\n
Run Code Online (Sandbox Code Playgroud)\n


Ten*_*eff 6

我还没有看到 Jestdescribe.each(table)被广泛使用,但它对于重用具有共同/相同结果的测试确实很有帮助。

\n\n

如果两个测试对象的期望相同,您可以这样做:

\n\n
const aCutePet = pet => {\n  it("should be small", () => {\n    expect(pet.size).toBeLessThan(10);\n  });\n\n  it(`should be able to smile`, () => {\n    expect(pet).toHaveProperty(\'can_smile\', true)\n  });\n}\n\ndescribe.each([\n  [new Doge],\n  [new Octocat]\n])("The %O", aCutePet);\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出:

\n\n
  The Doge { size: 3, can_smile: true }\n    \xe2\x9c\x93 should be small (1ms)\n    \xe2\x9c\x93 should be able to smile (1ms)\n  The Octocat { size: 5, can_smile: true }\n    \xe2\x9c\x93 should be small\n    \xe2\x9c\x93 should be able to smile (1ms)\n
Run Code Online (Sandbox Code Playgroud)\n


gui*_*ui3 5

如果你仍然想要beforeEach

由于原因......如果您在全局范围内声明变量,它就会起作用

let petSetInBefore; // here it works
describe('Famous animals', () => {
  //let petSetInBefore; // here it's undefined

  describe('Octocat', ()  => {
    //let petSetInBefore; // undefined too

    beforeAll(() => {
      petSetInBefore = new Octocat();
    })

    cutenessTests() // .bind(this) results the same
  });

  describe('Doge', () => {
    beforeEach(() => {
      petSetInBefore = new Doge();
    })

    cutenessTests.bind(this)()
  });
})
Run Code Online (Sandbox Code Playgroud)

https://repl.it/@gui3/jestSharedTests

似乎共享函数内的测试无法共享beforeEach中的变量,否则......