beforeEach hook issue #3359
-
avajs beforeEach hook issueI have test cases where a foo.js/**
* A Foo object that has a bar method which has its calls tracked in a "mock" object property.
*/
function Foo() {
const mock = { calls: [] }
Object.getPrototypeOf(this.bar).mock = mock
this.bar = function() {
mock.calls.push({ arguments })
}
}
Foo.prototype.bar = function() {}
export default Foo What's wrongRunning tests in parallel causes the
Tested on versions:
Inside the following env:
Actualcall-from-within-case.ava.test.js (KO)import ava from "ava"
import Foo from "./foo.js"
ava.beforeEach((test) => {
test.context.foo = new Foo()
})
ava("Call from within test case: Case 1", (test) => {
const { foo } = test.context
test.context.foo.bar({ foo: test.context.foo })
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ava("Call from within test case: Case 2", (test) => {
const { foo } = test.context
test.context.foo.bar({ foo: test.context.foo })
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ava("Call from within test case: Case 3", (test) => {
const { foo } = test.context
test.context.foo.bar({ foo: test.context.foo })
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
}) call-from-within-hook.ava.test.js (KO)import ava from "ava"
import Foo from "./foo.js"
ava.beforeEach((test) => {
test.context.foo = new Foo()
test.context.foo.bar({ foo: test.context.foo })
})
ava("Call from within hook: Case 1", (test) => {
const { foo } = test.context
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ava("Call from within hook: Case 2", (test) => {
const { foo } = test.context
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ava("Call from within hook: Case 3", (test) => {
const { foo } = test.context
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
}) no-hook.ava.test.js (OK)import ava from "ava"
import Foo from "./foo.js"
ava("No hook: Case 1", (test) => {
const foo = new Foo()
foo.bar({ foo })
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ava("No hook: Case 2", (test) => {
const foo = new Foo()
foo.bar({ foo })
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ava("No hook: Case 3", (test) => {
const foo = new Foo()
foo.bar({ foo })
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
}) serial.ava.test.js (OK)import ava from "ava"
import Foo from "./foo.js"
ava.serial.beforeEach((test) => {
test.context.foo = new Foo()
test.context.foo.bar({ foo: test.context.foo })
})
ava.serial("Serial: Case 1", (test) => {
const { foo } = test.context
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ava.serial("Serial: Case 2", (test) => {
const { foo } = test.context
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ava.serial("Serial: Case 3", (test) => {
const { foo } = test.context
test.is(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
}) call-from-within-hook.node.test.js (OK)import nodeTest from 'node:test';
import assert from 'node:assert/strict';
import Foo from "./foo.js"
nodeTest.beforeEach((test) => {
test.foo = new Foo()
test.foo.bar({ foo: test.foo })
})
nodeTest("Call from within hook (Node): Case 1", (test) => {
const { foo } = test
assert.strictEqual(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
nodeTest("Call from within hook (Node): Case 2", (test) => {
const { foo } = test
assert.strictEqual(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
nodeTest("Call from within hook (Node): Case 3", (test) => {
const { foo } = test
assert.strictEqual(
foo.bar.mock.calls[0].arguments[0].foo.bar.prototype,
foo.bar.prototype,
"Case 1 foo.bar.prototype strict equality failed"
)
})
ExpectedIt is expected that all tests pass. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This modifies a global value ( Even if hooks and tests are synchronous functions, hooks and tests may interleave (have not looked at the exact logic). So what this means is when the tests run, the |
Beta Was this translation helpful? Give feedback.
This modifies a global value (
Foo.prototype.bar.constructor.prototype
, beingFunction.prototype
):https://github.com/thoughtsunificator/avajs-before-each-hook-issue/blob/f857788c6416947cd1e193cbd6e7d5b9ce57032e/src/foo.js#L6
Even if hooks and tests are synchronous functions, hooks and tests may interleave (have not looked at the exact logic). So what this means is when the tests run, the
mock
value will be of the last instantiatedFoo
, not thefoo
object from the execution context.