2016-12-03 5 views
8

Я создаю приложение с React Native. Я хочу свести к минимуму, как часто я общаюсь с базой данных, поэтому я активно использую AsyncStorage. Есть много места для ошибок в переводе между БД и AsyncStorage. Поэтому я хочу убедиться, что AsyncStorage имеет данные, которые, как я полагаю, он делает, запуская автоматические тесты против него. Удивительно, но я не нашел никакой информации о том, как это сделать в Интернете. Мои попытки сделать это сами по себе не сработали.Как протестировать Async Storage с помощью Jest?

Использование шутя:

it("can read asyncstorage",() => { 
return AsyncStorage.getItem('foo').then(foo => { 
    expect(foo).not.toBe(""); 
}); }); 

Этот метод потерпел неудачу с ошибкой:

TypeError: RCTAsyncStorage.multiGet is not a function 

Удаление возвращение заставит его работать немедленно, не дожидаясь значения и неправильно пройти тест.

я получил удар с той же самой ошибкой, когда я попытался проверить его с помощью ключевого слова ЖДЕТ:

it('can read asyncstorage', async() => { 
this.foo = ""; 
await AsyncStorage.getItem('foo').then(foo => { 
    this.foo = foo; 
}); 
expect(foo).not.toBe(""); }); 

Любые предложения о том, как успешно запустить утверждения против значений в AsyncStorage? Я предпочел бы продолжать использовать Jest, но если это можно сделать только с помощью некоторой альтернативной библиотеки тестирования, я открыт для этого.

ответ

5

Мой первоначальный ответ только указал на как автор реакции-native-simple-store имел дело с насмешкой. Я обновил свой ответ своим собственным издевательством, которое удаляет жестко закодированные ответы Джейсона.

Jason Merino имеет приятный простой подход к этому в https://github.com/jasonmerino/react-native-simple-store/blob/master/tests/index-test.js#L31-L64

jest.mock('react-native',() => ({ 
AsyncStorage: { 
    setItem: jest.fn(() => { 
     return new Promise((resolve, reject) => { 
      resolve(null); 
     }); 
    }), 
    multiSet: jest.fn(() => { 
     return new Promise((resolve, reject) => { 
      resolve(null); 
     }); 
    }), 
    getItem: jest.fn(() => { 
     return new Promise((resolve, reject) => { 
      resolve(JSON.stringify(getTestData())); 
     }); 
    }), 
    multiGet: jest.fn(() => { 
     return new Promise((resolve, reject) => { 
      resolve(multiGetTestData()); 
     }); 
    }), 
    removeItem: jest.fn(() => { 
     return new Promise((resolve, reject) => { 
      resolve(null); 
     }); 
    }), 
    getAllKeys: jest.fn(() => { 
     return new Promise((resolve) => { 
      resolve(['one', 'two', 'three']); 
     }); 
    }) 
    } 
})); 

Мой собственный макет:

const items = {}; 

jest.mock('react-native',() => ({ 

AsyncStorage: {   

    setItem: jest.fn((item, value) => { 
     return new Promise((resolve, reject) => {   
    items[item] = value; 
      resolve(value); 
     }); 
    }), 
    multiSet: jest.fn((item, value) => { 
     return new Promise((resolve, reject) => { 
    items[item] = value; 
      resolve(value); 
     }); 
    }), 
    getItem: jest.fn((item, value) => { 
     return new Promise((resolve, reject) => { 
      resolve(items[item]); 
     }); 
    }), 
    multiGet: jest.fn((item) => { 
     return new Promise((resolve, reject) => { 
      resolve(items[item]); 
     }); 
    }), 
    removeItem: jest.fn((item) => { 
     return new Promise((resolve, reject) => { 
      resolve(delete items[item]); 
     }); 
    }), 
    getAllKeys: jest.fn((items) => { 
     return new Promise((resolve) => { 
      resolve(items.keys()); 
     }); 
    }) 
    } 
})); 
+0

Это решение будет работать только для вашего варианта использования, нижеприведенное решение должно быть принято! – Ouadie

+0

@ Нужно редактировать, поэтому определены 'multiGet' и' multiSet'. @ brian-case спрашивал конкретно о 'multiGet'. Я выкопаю, как я закончил издеваться над моим, избегая жестко запрограммированных ответов на 'resolve()' – jaygooby

+0

Получение «Не удается найти модуль« AsyncStorage »из« response-native-implementation.js »в моем тесте при использовании вашего макет - любая идея, почему? :) @jaygooby – jhm

12

Может быть, вы можете попробовать что-то вроде этого:

mockStorage.js

export default class MockStorage { 
    constructor(cache = {}) { 
    this.storageCache = cache; 
    } 

    setItem = jest.fn((key, value) => { 
    return new Promise((resolve, reject) => { 
     return (typeof key !== 'string' || typeof value !== 'string') 
     ? reject(new Error('key and value must be string')) 
     : resolve(this.storageCache[key] = value); 
    }); 
    }); 

    getItem = jest.fn((key) => { 
    return new Promise((resolve) => { 
     return this.storageCache.hasOwnProperty(key) 
     ? resolve(this.storageCache[key]) 
     : resolve(null); 
    }); 
    }); 

    removeItem = jest.fn((key) => { 
    return new Promise((resolve, reject) => { 
     return this.storageCache.hasOwnProperty(key) 
     ? resolve(delete this.storageCache[key]) 
     : reject('No such key!'); 
    }); 
    }); 

    clear = jest.fn((key) => { 
    return new Promise((resolve, reject) => resolve(this.storageCache = {})); 
    }); 

    getAllKeys = jest.fn((key) => { 
    return new Promise((resolve, reject) => resolve(Object.keys(this.storageCache))); 
    }); 
} 

и внутри вашего тестового файла:

import MockStorage from './MockStorage'; 

const storageCache = {}; 
const AsyncStorage = new MockStorage(storageCache); 

jest.setMock('AsyncStorage', AsyncStorage) 

// ... do things 
+1

Получение «Не удается найти модуль« AsyncStorage »из« myFileName.js », несмотря на попытку импортировать его из« реагировать-родной »- любые идеи? :) – jhm

+0

Должен быть принят ответ, так как он наиболее четко отвечает на вопрос происхождения – mcabe

-1

Для тех, кто еще, чтобы получить здесь, asyncStorage также нужен обратный вызов, некоторые ЛИЭС использовать этот