英文:
Not all computations get settled when testing a complex effector application with fork and mocked handlers
问题
我正在努力测试下面的效应程序:
// === module1.js ===
export const $storeA = createStore({testA: false});
export const $storeB = createStore({testB: false});
export const fetchDataFx = createEffect(() => someAsyncFnUsingAxios());
// === module2.js ===
$storeB.on(fetchDataFx.doneData, (_, {data}) => ({testB: data}));
// === module3.js ===
export const $storeC = combine($storeA, $storeB).map(([storeA, storeB]) => storeA && storeB);
// === module3.test.js ===
import {fetchDataFx, $storeA} from 'module1';
import {$storeC} from 'module3';
describe('some test', () => {
test('should return true when fetched data is true', async () => {
const scope = fork({
handlers: [
[fetchDataFx, () => Promise.resolve({data: true})],
],
values: [
[$storeA, {testA: true}],
// not setting $storeB on purpose, as we want to test whether the fetched data is stored and calculated
],
});
await allSettled(fetchDataFx, {scope});
expect(scope.getState($storeC)).toBe(true); // FAILS!
});
});
模拟的处理程序被调用了,但是
$storeB.on(fetchDataFx.doneData, (_, {data}) => ({testB: data}));
没有被触发!
有什么想法吗?
我尝试了遵循 https://dev.to/effector/the-best-part-of-effector-4c27 上的说明。
我还尝试用普通的存储替换派生存储并使用 sample 进行更新:
export const $storeC = createStore(false);
sample({
source: [$storeA, $storeB],
fn: ([storeA, storeB]) => storeA && storeB,
target: $storeC
});
但这也没有起作用。
英文:
I'm struggling to get the below effector application tested:
// === module1.js ===
export const $storeA = createStore({testA: false});
export const $storeB = createStore({testB: false});
export const fetchDataFx = createEffect(() => someAsyncFnUsingAxios());
// === module2.js ===
$storeB.on(fetchDataFx.doneData, (_, {data}) => ({testB: data}));
// === module3.js ===
export const $storeC = combine($storeA, $storeB).map(([storeA, storeB]) => storeA && storeB);
// === module3.test.js ===
import {fetchDataFx, $storeA} from 'module1';
import {$storeC} from 'module3';
describe('some test', () => {
test('should return true when fetched data is true', async () => {
const scope = fork({
handlers: [
[fetchDataFx, () => Promise.resolve({data: true})],
],
values: [
[$storeA, {testA: true}],
// not setting $storeB on purpose, as we want to test whether the fetched data is stored and calculated
],
});
await allSettled(fetchDataFx, {scope});
expect(scope.getState($storeC)).toBe(true); // FAILS!
});
});
The mocked handler gets called, but
$storeB.on(fetchDataFx.doneData, (_, {data}) => ({testB: data}));
does not get triggered!
Any ideas?
I've tried following the instructions from https://dev.to/effector/the-best-part-of-effector-4c27
I've also tried replacing the derived store with a regular one and use sample to make it update:
export const $storeC = createStore(false);
sample({
source: [$storeA, $storeB],
fn: ([storeA, storeB]) => storeA && storeB,
target: $storeC
});
but it also didn't work.
答案1
得分: 0
问题原来出在导入上。测试模块必须导入任何定义了一些效应计算的模块,以便 effector 能够意识到它们。现在显而易见... <叹气>
// === module3.test.js ===
import {fetchDataFx, $storeA} from 'module1';
import {$storeC} from 'module3';
import 'module2'; // <-- 这解决了问题
describe('some test', () => {
test('should return true when fetched data is true', async () => {
const scope = fork({
handlers: [
[fetchDataFx, () => Promise.resolve({data: true})],
],
values: [
[$storeA, {testA: true}],
// not setting $storeB on purpose, as we want to test whether the fetched data is stored and calculated
],
});
await allSettled(fetchDataFx, {scope});
expect(scope.getState($storeC)).toBe(true); // 成功!
});
});
英文:
The problem turned out to be with imports. The test module must import any module that has some effector computations defined in order for effector to be aware of them. So obvious now ... <sigh>
// === module3.test.js ===
import {fetchDataFx, $storeA} from 'module1';
import {$storeC} from 'module3';
import 'module2'; // <-- this solves the problem
describe('some test', () => {
test('should return true when fetched data is true', async () => {
const scope = fork({
handlers: [
[fetchDataFx, () => Promise.resolve({data: true})],
],
values: [
[$storeA, {testA: true}],
// not setting $storeB on purpose, as we want to test whether the fetched data is stored and calculated
],
});
await allSettled(fetchDataFx, {scope});
expect(scope.getState($storeC)).toBe(true); // SUCCEEDS!
});
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论