Я работаю с API, который не возвращает ничего похожего на ошибку при неправильном входе в систему (просто обычный объект с кодом — incorrect_password
или invalid_username
— HTML-сообщение), поэтому в моей функции вызова API я m превращая код в ошибку:
export async function loginWithApi(creds) {
try {
const res = await axios.get(ApiUrls.login, { params: creds });
if (res.data.data) {
return res.data;
} else if (res.data.code) {
throw Error(res.data.code.titleize());
} // else, it should be an actual error
} catch (err) {
return err;
}
}
Это работает правильно, выдает правильно, возвращает ошибку, когда должно.
Однако при тестировании моего действия генератора саги, которое вызывает эту функцию, ошибка не обнаруживается, она не ослабевает в блоке try
:
export function* loginSaga({ username, password }) {
const creds = { username, password };
try {
const res = yield call(loginWithApi, creds);
console.info(res);
yield put({ type: "LOGIN_SUCCESS", user: res.data });
} catch (error) {
yield put({ type: "LOGIN_FAILURE", error });
}
}
describe("login action", () => {
let gen;
afterEach(() => {
expect(gen.next().done).toBe(true);
});
it("should return a user object on a successful login", () => {
gen = loginSaga(success.creds);
gen.next(); // call api
expect(gen.next(mockResponse.success).value).toEqual(
put({ type: "LOGIN_SUCCESS", user: mockResponse.success.data })
);
});
it("should return an error when passed an invalid username", () => {
gen = loginSaga(badUser.creds);
gen.next(); // call api
// mockReponse.usernameError: Error("Invalid Username")
expect(gen.next(mockResponse.usernameError).value).toEqual(
put({ type: "LOGIN_FAILURE", error: "Invalid Username" })
);
});
it("should return an error when passed an invalid password", () => {
gen = loginSaga(badPw.creds);
gen.next(); // call api
// mockResponse.passwordError: Error("Incorrect Password"),
expect(gen.next(mockResponse.passwordError).value).toEqual(
put({ type: "LOGIN_FAILURE", error: "Incorrect Password" })
);
});
});
● Saga Actions › login action › should return an error when passed an invalid username
expect(received).toEqual(expected) // deep equality
- Expected
+ Received
Object {
"@@redux-saga/IO": true,
"combinator": false,
"payload": Object {
"action": Object {
- "error": "Invalid Username",
- "type": "LOGIN_FAILURE",
+ "type": "LOGIN_SUCCESS",
+ "user": undefined,
},
"channel": undefined,
},
"type": "PUT",
● Saga Actions › login action › should return an error when passed an invalid password
expect(received).toEqual(expected) // deep equality
- Expected
+ Received
Object {
"@@redux-saga/IO": true,
"combinator": false,
"payload": Object {
"action": Object {
- "error": "Incorrect Password",
- "type": "LOGIN_FAILURE",
+ "type": "LOGIN_SUCCESS",
+ "user": undefined,
},
"channel": undefined,
},
"type": "PUT",
}
Регистрация подтверждает, что loginSaga
функция является получает Error
во вторых двух тестах. Я не могу точно определить, почему эта ошибка не обнаруживается.
Наконец-то понял.
Поэтому вам нужно заставить генератор думать, что Exception произошло для одного из его yield
. Для этого у нас есть generator.prototype.throw()
.
Итак, следующий код должен работать так, как ожидалось:
it("should return an error when passed an invalid username", () => {
gen = loginSaga(badUser.creds);
gen.next(); // call api
// mockReponse.usernameError: Error("Invalid Username")
expect(gen.throw(mockResponse.usernameError).value).toEqual(
put({ type: "LOGIN_FAILURE", error: "Invalid Username" })
);
});