Ваша ложная функция неверна.jest.fn
без аргументов просто предоставляет фиктивную функцию, которая возвращает undefined
.Вам нужен тот, который возвращает что-то на основе аргумента, который он получает.Возможно:
const foo = jest.fn(x => x);
Тогда , как я сказал в комментарии , это ненадежно:
if (cachedValue[arg]) {
Что если foo
вернет 0
?Или ""
?Или null
?Или undefined
?(Как на самом деле ваша фиктивная функция.)
Вместо этого используйте
if (Object.prototype.hasOwnProperty.call(cachedValue, arg)) {
Но, как сказал @NinaScholz: это работает, только если аргумент arg может быть разумно приведен к строке без потериинформация / вызывающая ложные совпадения.Карта была бы лучшим выбором, и использование WeakMap, когда arg
является объектом, было бы еще лучше.
Для чего стоит:
function cacheFunction(foo) {
const cachedValuesByPrimitive = new Map();
const cachedValuesByObject = new WeakMap();
return (arg) => {
const cache = typeof arg === "object" && arg !== null
? cachedValuesByObject
: cachedValuesByPrimitive;
if (cache.has(arg)) {
return cache.get(arg);
}
const result = foo(arg);
cache.set(arg, result);
return result;
};
}
export { cacheFunction };
Live Пример:
function cacheFunction(foo) {
const cachedValuesByPrimitive = new Map();
const cachedValuesByObject = new WeakMap();
return (arg) => {
const cache = typeof arg === "object" && arg !== null
? cachedValuesByObject
: cachedValuesByPrimitive;
if (cache.has(arg)) {
return cache.get(arg);
}
const result = foo(arg);
cache.set(arg, result);
return result;
};
}
function foo(x) {
console.log("foo called for", x);
return x;
}
const cachingFoo = cacheFunction(foo);
cachingFoo(true);
cachingFoo(true);
cachingFoo(true);
cachingFoo(true);
cachingFoo(10);
cachingFoo(10);
cachingFoo(10);
cachingFoo(10);
const obj1 = {a: 1};
cachingFoo(obj1);
cachingFoo(obj1);
const obj2 = {a: 2};
cachingFoo(obj2);
cachingFoo(obj2);
cachingFoo(obj2);