我的ES6 User类中有以下功能,用于搜索给定字符串的用户。
// Search for a user by their pNick, includes partial matching
static getBypNick(pNick = '') {
// Define our search criteria regex and normalise to lower case
const userSearchRegex = new RegExp(`^${pNick.toLowerCase()}`, 'i')
return new Promise((resolve, reject) => {
// Search user collection for pNick using regex like search and return array of results
userTable.find({
_pNick: userSearchRegex
}).sort({
_pNick: 1
}).exec(function (err, result) {
// If error reject
if (err) {
return reject(err)
}
const userArray = result.map((user) => {
return new User(
user._pNick,
user._firstName,
user._userName,
user._phoneNumber,
user._userID)
})
// Return user records if found
return resolve(userArray)
})
})
}
虽然我可以使用Jest轻松测试成功路由,但我很难理解如何调用错误情况,特别是在函数中的.exec方法中调用promise中的拒绝路由。
我知道我可以使用各种Jest功能,例如mockImplementation,但我无法弄清楚这种情况下的最佳情况。在幕后使用的数据库是NeDB,我非常肯定我只需要强制.exec部分返回错误然后我应该在我的承诺中捕获它。
我无意测试底层的NeDB库,因为它有自己的测试成功执行,所以这完全是我自己的方法。
答案 0 :(得分:0)
这是单元测试解决方案:
userRepo.js
:
import { userTable } from './userTable';
import { User } from './user';
export class UserRepo {
static getBypNick(pNick = '') {
const userSearchRegex = new RegExp(`^${pNick.toLowerCase()}`, 'i');
return new Promise((resolve, reject) => {
userTable
.find({
_pNick: userSearchRegex,
})
.sort({
_pNick: 1,
})
.exec(function(err, result) {
if (err) {
return reject(err);
}
const userArray = result.map((user) => {
return new User(user._pNick, user._firstName, user._userName, user._phoneNumber, user._userID);
});
return resolve(userArray);
});
});
}
}
userTable.js
:
const userTable = {
find() {
return this;
},
sort() {
return this;
},
exec(fn) {
console.log('real exec');
fn();
},
};
user.js
:
export class User {
constructor(nick, firstName, userName, phoneNumber, userId) {
this.nick = nick;
this.firstName = firstName;
this.userName = userName;
this.phoneNumber = phoneNumber;
this.userId = userId;
}
}
userRepo.test.js
:
import { UserRepo } from './userRepo';
import { userTable } from './userTable';
jest.mock('./userTable', () => {
const mUserTable = {
find: jest.fn().mockReturnThis(),
sort: jest.fn().mockReturnThis(),
exec: jest.fn(),
};
return { userTable: mUserTable };
});
describe('47587358', () => {
afterAll(() => {
jest.resetAllMocks();
});
it('should get user by nick', async () => {
const mResult = [{ _pNick: '_pNick', _firstName: '_firstName', _userName: '_userName', _phoneNumber: 123456, _userID: 1 }];
userTable.exec.mockImplementationOnce((fn) => {
fn(null, mResult);
});
const actual = await UserRepo.getBypNick('jest');
expect(actual).toEqual(
expect.arrayContaining([
expect.objectContaining({
nick: expect.any(String),
firstName: expect.any(String),
userName: expect.any(String),
phoneNumber: expect.any(Number),
userId: expect.any(Number),
}),
]),
);
expect(userTable.find).toBeCalledWith({ _pNick: new RegExp(`^jest`, 'i') });
expect(userTable.sort).toBeCalledWith({ _pNick: 1 });
expect(userTable.exec).toBeCalledWith(expect.any(Function));
});
it('should handle error', async () => {
const mError = new Error('network');
userTable.exec.mockImplementationOnce((fn) => {
fn(mError, null);
});
await expect(UserRepo.getBypNick('jest')).rejects.toThrowError('network');
expect(userTable.find).toBeCalledWith({ _pNick: new RegExp(`^jest`, 'i') });
expect(userTable.sort).toBeCalledWith({ _pNick: 1 });
expect(userTable.exec).toBeCalledWith(expect.any(Function));
});
});
具有覆盖率报告的单元测试结果:
PASS src/stackoverflow/47587358/userRepo.test.js (9.448s)
47587358
✓ should get user by nick (10ms)
✓ should handle error (3ms)
-------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-------------|----------|----------|----------|----------|-------------------|
All files | 100 | 66.67 | 100 | 100 | |
user.js | 100 | 100 | 100 | 100 | |
userRepo.js | 100 | 66.67 | 100 | 100 | 5 |
-------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 10.66s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/47587358