我正在使用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,但如果它只能通过一些备用测试库来完成,我会对此持开放态度。
答案 0 :(得分:8)
我的原始答案只是指出了react-native-simple-store的作者是如何处理嘲弄的。我用自己的嘲讽更新了我的答案,删除了Jason的硬编码模拟回复。
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());
});
})
}
}));
答案 1 :(得分:4)
对于在> 2019年看到此问题的每个人:
自February 2019起, AsyncStorage已移至@react-native-community/async-storage ,如果从react-native
导入警告,则会出现此警告:
Warning: Async Storage has been extracted from react-native core and will be removed in a future release.
新模块包括其自己的模拟程序,因此您不必担心再编写自己的模块。
Per the project's documentation,您可以通过2种不同的方式进行设置:
__mocks__/@react-native-community
目录。export default from '@react-native-community/async-storage/jest/async-storage-mock'
然后,在所有测试中,默认情况下,Jest应该模拟AsyncStorage
。如果不是,请尝试在测试文件的顶部调用jest.mock(@react-native-community/async-storage)
。package.json
或jest.config.js
中)添加设置文件的位置:
"jest": {
"setupFiles": ["./path/to/jestSetupFile.js"]
}
在您的设置文件中,设置AsyncStorage模拟:
import mockAsyncStorage from '@react-native-community/async-storage/jest/async-storage-mock';
jest.mock('@react-native-community/async-storage', () => mockAsyncStorage);
如果您使用的是TypeScript ,则使用第二个选项(Jest安装文件)会更容易,因为使用第一个选项(mocks目录)不会将@types/react-native-community__async-storage
与自动模拟。
答案 2 :(得分:0)
我认为jest.setMock在这种情况下可能比jest.mock更好,因此我们可以毫无疑问地使用react-native
来模拟AsyncStorage
,就像这样:
jest.setMock('AsyncStorage', {
getItem: jest.fn(
item =>
new Promise((resolve, reject) => {
resolve({ myMockObjectToReturn: 'myMockObjectToReturn' });
})
),
});
答案 3 :(得分:0)
使用以下命令安装模块: 从项目的根目录运行此命令。
npm install --save mock-async-storage
在项目根目录中,创建__mocks__\@react-native-community
文件夹。在其中创建一个文件async-storage.js。
async-storage.js中的代码
export default from '@react-native-community/async-storage/jest/async-storage-mock'
在package.json内部配置笑话如下:
"jest": {
"preset": "jest-expo",
"transformIgnorePatterns" : ["/node_modules/@react-native-community/async-storage/(?!(lib))"]
},
在这里,我正在使用jest-expo进行测试。如果您使用的是jest,则预设值为jest,而不是jest-expo。
在项目根目录中,创建一个名为jest.config.js的文件 jest.config.js文件中的配置:
module.exports = {
setupFilesAfterEnv: [
'./setup-tests.js',
],
};
在项目根目录中,创建一个名为setup-tests.js的文件。该文件中的代码是:
import MockAsyncStorage from 'mock-async-storage';
const mockImpl = new MockAsyncStorage();
jest.mock('@react-native-community/async-storage', () => mockImpl);
在项目根目录中创建测试文件。在这里,我称它为Example.test.js。
import AsyncStorage from '@react-native-community/async-storage';
beforeEach(() => {
AsyncStorage.clear();
// console.log(`After the data is being reset :`)
// console.log(AsyncStorage)
});
it('can read asyncstorage', async () => {
await AsyncStorage.setItem('username', 'testUser')
let usernameValue = await AsyncStorage.getItem('username')
// console.log(`After the data is being set :`)
// console.log(AsyncStorage)
expect(usernameValue).toBe('testUser')
});
在此处使用AsyncStorage.setItem将用户名的值设置为testUser。然后使用getItem函数获取值。 测试用例是比较usernameValue是否等于testUser。 如果是,则测试用例通过,否则测试用例将失败。
使用beforeEach以便每次运行测试用例时,Asyncstorage都会被清除并且为空。 如果需要,可以使用console.log
检查Asyncstorage中的内容。运行命令 yarn test 来运行测试。输出为:
答案 4 :(得分:0)
我刚刚在最新版本的 Expo 上运行 jest 时遇到了这个问题,并按照 https://react-native-async-storage.github.io/async-storage/docs/advanced/jest/ 上的说明中的“jest setup file”选项解决了这个问题。
请注意,AsyncStorage 已(无论出于何种原因)重命名\移回“@react-native-async-storage/async-storage”,并且其包名称中不再包含“community”。
答案 5 :(得分:0)
1- 在根项目中添加文件夹 __mocks__
2- 在 @react-native-async-storage
文件夹中添加文件夹 __mocks__
3- 在 async-storage.js
中添加文件 @react-native-async-storage
4- 添加代码:
let db = {};
export default {
setItem: (item, value) => {
return new Promise((resolve, reject) => {
db[item] = value;
resolve(value);
});
},
multiSet: (item, fun) => {
return new Promise((resolve, reject) => {
for (let index = 0; index < item.length; index++) {
db[item[index][0]] = item[index][1];
}
fun()
resolve(value);
});
},
getItem: (item, value= null) => {
return new Promise((resolve, reject) => {
resolve(db[item]);
});
},
multiGet: (item) => {
return new Promise((resolve, reject) => {
resolve(db[item]);
});
},
removeItem: (item) => {
return new Promise((resolve, reject) => {
resolve(delete db[item]);
});
},
getAllKeys: (db) => {
return new Promise((resolve) => {
resolve(db.keys());
});
}
}
答案 6 :(得分:-1)
对于其他任何人来说,asyncStorage也需要一个回调,一些libs使用这个