我正在为此代码编写测试,您可以忽略除await addRefreshToken(existingUser, refresh);
我正在为此编写测试用例,无论出于什么原因,我都无法克服addRefreshToken,我对其进行了正确的模拟,甚至对其进行了正确调用(我对实现进行了模拟以执行console.log),但是无论如何都无法实现不管我尝试了什么。您可以看到我有req.test();
的下一行,这是我用笑话传递给req对象的模拟函数(笑话中不是真实的东西,只是我正在测试的东西。
const appleLogin = (req, res, model) => {
try {
const requestBody = {
grant_type: "authorization_code",
code: req.body.code,
redirect_uri: process.env.kic_apple_signin_redirect_uri,
client_id: process.env.kic_apple_signin_client_id,
client_secret: appleClientSecretGen(),
scope: "email fullName",
};
axios
.request({
method: "POST",
url: "https://appleid.apple.com/auth/token",
data: qs.stringify(requestBody),
headers: { "Content-Type": "application/x-www-form-urlencoded" },
})
.then(async response => {
const { sub, email, is_private_email: isPrivateEmail } = jwt.decode(
response.data.id_token,
);
// $or statement allows users to login with their apple email if they dont private it
const existingUser = await model.findOne({
$or: [{ apple_signin_user_id: sub }, { email }],
});
if (existingUser) {
const { token, refresh } = generateTokens({
payload: { _id: existingUser._id },
});
if (!existingUser.apple_signin_user_id) {
existingUser.apple_signin_user_id = sub;
await existingUser.save();
}
await addRefreshToken(existingUser, refresh);
req.test();
const populatedUser = await model
.findById(existingUser)
.populate({
path: "roles titles goal meal_type subscription",
options: { lean: true },
})
.lean();
if (!populatedUser) {
console.error("1");
const errObj = generateApiErr({
status: 500,
message: "Something went wrong retrieving this user",
origin: "mongodb",
action: "user.appleLogin.modelPopulate",
});
return res.status(errObj.error.status).json(errObj);
}
// console.error("2");
return res.status(200).json({
id: populatedUser._id,
token,
user: populatedUser,
refreshToken: refresh,
});
}
})
.catch(e => {
console.error(
"APPLE::SIGNIN::ERR::AXIOS",
e.response ? e.response.data : e,
);
console.error(res, res.status, res.status.json);
const errObj = generateApiErr({
status: 500,
message: "Something went wrong verifying this token",
origin: "apple",
action: "user.appleLogin.axiosTryCatch",
});
res.status(errObj.error.status).json(errObj);
});
} catch (e) {
console.log(e);
const errObj = generateApiErr({
status: 500,
message: e.message,
origin: "apple",
action: "user.appleLogin.axiosTryCatch",
});
res.status(errObj.error.status).json(errObj);
}
};
这是测试文件
import { addRefreshToken } from "../../../lib/util/addRefreshToken";
import User from "../User";
jest.mock("../../../lib/util/addRefreshToken", () => ({
addRefreshToken: jest.fn(),
}));
describe("Apple login", () => {
let req;
let res;
let model;
let user;
let findOne;
let findById;
let populate;
let lean;
const fakeActionTeest = jest.fn(() => console.log("wtf?"));
const action = User.appleLoginRoute.action;
beforeEach(() => {
req = {
__MOCK: "request",
path: "foo.bar",
body: { code: "__CODE__" },
test: fakeActionTeest,
};
res = getMockRes();
const encodedData = jwt.sign(
{
sub: "__APPLE_ID__",
email: "test@playsidestudios.com",
is_private_email: false,
},
"anything",
);
axios.request.mockImplementationOnce(() =>
Promise.resolve({ data: { id_token: encodedData }, status: 200 }),
);
user = { _id: "__USER_ID__", apple_signin_user_id: "__APPLE_ID__" };
findOne = jest.fn(() => Promise.resolve(user));
lean = jest.fn();
lean.mockReturnValueOnce(
Promise.resolve({ ...user, roles: [{ _id: "_ROLE_" }] }),
);
populate = jest.fn(() => ({ lean }));
findById = jest.fn(() => ({ populate }));
model = { __MOCK: "model", findOne, findById };
addRefreshToken.mockImplementationOnce(() => console.log("FWAFAWF"));
});
it("Should log an existing user in", async () => {
await action(req, res, model);
expect(addRefreshToken).toHaveBeenCalledTimes(1); // This works tho, and does a console log!
expect(fakeActionTeest).toHaveBeenCalledTimes(1); // Fails here
});
});
很抱歉,我无法确定要删除多少文字而不破坏上下文
测试失败,因为预计falseActionTeest将被调用一次,但被调用0次
因此它没有通过addRefreshTooken,但它是调用控制台日志“ FWAFAWF”,如下图所示(忽略控制台日志的错误,我们只有一个过滤器来标记它们)