2016-12-03 9 views
8

私はReact Nativeでアプリを構築しています。データベースとの通信頻度を最小限に抑えたいので、AsyncStorageを大量に使用しています。しかし、DBとAsyncStorageの間の翻訳にはバグの余地がたくさんあります。したがって、AsyncStorageには、自動化されたテストを実行していると信じているデータがあることを確認したいと思います。驚いたことに、私はオンラインでそれを行う方法に関する情報は見つかりませんでした。それを自分でしようとする私の試みはうまくいかない。冗談を使用してJestを使って非同期ストレージをテストするには?

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

このメソッドは、エラーで失敗しました:リターンを削除

TypeError: RCTAsyncStorage.multiGet is not a function 

は、それが値を待たずに即座に実行する原因と不適切なテストを通過します。私はのawaitキーワードを使用してそれをテストしようとしたとき

私は正確に同じエラーで当たった:

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

成功しAsyncStorageの値に対してアサーションを実行する方法上の任意の提案は?私はJestを使い続けるのが好きですが、もしそれがいくつかの代替のテストライブラリでしかできないなら、私はそれを公開しています。

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

とあなたのテストファイル内側:

答えて

5

どのように反応ネイティブシンプルストアの作者が嘲笑を扱っていたのか。私はJasonのハードコーディングされたモックレスポンスを削除する自分の嘲笑で自分の答えを更新しました。

Jason Merinohttps://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

@Uuadie編集が必要なので、 'multiGet'と' multiSet'が定義されています。 @ brian-caseは特に 'multiGet'について質問していました。私は私の嘲笑を解決し、解決した解決策を避けています。 – jaygooby

+0

あなたのアプリケーションを使用する際に 'Reason-native-implementation.js'モジュールから 'AsyncStorage'モジュールを見つけることができません。モック - 何か考えている理由? :) @jaygooby – jhm

12

は、あなたがこのような何かを試すことができかもしれませ私のオリジナルの答えはただで指摘

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も、コールバックを必要とする、いくつかのLIBSはこの

を使用
関連する問題