2016-12-03 17 views
8

Buduję aplikację z React Native. Chcę zminimalizować częstotliwość komunikacji z bazą danych, dlatego intensywnie korzystam z AsyncStorage. Jest dużo miejsca na błędy w tłumaczeniu między DB a AsyncStorage. Dlatego chciałbym się upewnić, że AsyncStorage ma dane, które moim zdaniem robią, uruchamiając zautomatyzowane testy przeciwko niemu. Co zaskakujące, nie znalazłem żadnych informacji, jak to zrobić w Internecie. Moje próby zrobienia tego na własną rękę nie wyszło.Jak testować pamięć asynchroniczną za pomocą?

Korzystanie żartem:

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

Metoda ta nie powiodła się z powodu błędu:

TypeError: RCTAsyncStorage.multiGet is not a function 

Zdejmowanie powrót spowoduje go uruchomić natychmiast, bez czekania na wartości i niewłaściwie zdać test.

zostałem uderzony z dokładnie tego samego błędu, gdy próbowałem go przetestować za pomocą słowa kluczowego czekają:

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

Wszelkie sugestie, w jaki sposób z powodzeniem uruchomić twierdzeń wobec wartości w AsyncStorage? Wolałbym nadal używać Jest, ale jeśli można to zrobić tylko z alternatywną biblioteką testową, jestem do tego otwarty.

Odpowiedz

5

Mój oryginalny odpowiedź tylko wskazał na w jaki sposób autor magazynu "native-simple-store" poradził sobie z kpiną. Zaktualizowałem swoją odpowiedź, kpiąc z mojego własnego kpina, który usuwa zakodowane reakcje Jasona.

Jason Merino ma ładne proste podejście do tego w 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']); 
     }); 
    }) 
    } 
})); 

Mój własny makiety:

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

To rozwiązanie będzie działać tylko w twoim przypadku użycia, poniższe rozwiązanie powinno być zaakceptowane! – Ouadie

+0

@Ouadie wymaga edycji, więc zdefiniowane są 'multiGet' i' multiSet'. @ brian-case pytał konkretnie o 'multiGet'. Wykopam, jak skończyłem się drwić z mojego, unikając zakodowanych odpowiedzi na 'resolve()' – jaygooby

+0

Uzyskiwanie "Nie można znaleźć modułu" AsyncStorage "z" react-native-implementation.js "w moim teście podczas używania twojego drwić - jakikolwiek pomysł, dlaczego? :) @jaygooby – jhm

12

Może być możesz spróbować czegoś takiego:

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))); 
    }); 
} 

i wewnątrz testowym pliku:

import MockStorage from './MockStorage'; 

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

jest.setMock('AsyncStorage', AsyncStorage) 

// ... do things 
+1

Uzyskiwanie "Nie można znaleźć modułu" AsyncStorage "z pliku" myFileName.js ", mimo próby zaimportowania go z" native-React "- jakichkolwiek pomysłów? :) – jhm

+0

Powinna być zaakceptowana odpowiedź, ponieważ najwyraźniej odpowiada na pytanie o pochodzenie – mcabe

-1

dla nikogo się tu dostać, asyncStorage potrzebuje również zwrotnego, niektóre libs użycia tej

Powiązane problemy