Я создал сервис для получения информации о пользователях от django rest auth
. Поэтому мне нужно 2 отдельных запроса. один для получения токена авторизации и один для получения информации о пользователе.
В службе userService
у меня есть метод с именем login
, который вызывает 2 других метода. Каждый из них отправляет запрос http на свой URL.
Для тестирования поведения login
мне нужно смоделировать запросы этих двух методов.
Первый метод возвращает Promise
, который включает в себя ключ аутентификации, а второй метод возвращает Promise
, который включает в себя объект пользователя.
Вот мой код в классе обслуживания:
public getAuthToken(identifier: string, password: string) {
const requestBody = is_valid_email(identifier) ? {email: identifier, password: password} :
{username: identifier, password: password};
let savedToken = getFromStorage('auth');
if (savedToken) {
try {
savedToken = JSON.parse(savedToken);
} catch (e) {
savedToken = null;
}
}
return new Promise((resolve, reject) => {
if (savedToken) {
resolve(savedToken);
} else {
this.http.post<string>(APIUrlSolver.login, requestBody).subscribe(data => {
const dataObj = JSON.parse(data);
UserService._auth_token = dataObj['key'];
resolve(dataObj['key']);
}, error1 => {
// Rejection code. removed for better reading
});
}
});
}
public getUserProfile(): Promise<UserModel> {
return new Promise<UserModel>((resolve, reject) => {
this.http.get(APIUrlSolver.user).subscribe((data: string) => {
const jsonData = JSON.parse(data);
const userObj = new UserModel(jsonData.username, jsonData.email, jsonData.first_name, jsonData.last_name, jsonData.phone,
jsonData.birth_date);
UserService._user = userObj;
resolve(userObj);
}, error1 => {
// Rejection code. removed for better reading
});
});
}
public login(identifier: string, password: string) {
return new Promise((resolve, reject) => {
this.getAuthToken(identifier, password).then(key => {
this.getUserProfile().then(user => {
// Will resolve user object
}).catch(error => {
UserService._auth_token = undefined;
reject(error);
});
}).catch(reason => {
UserService._auth_token = undefined;
reject(reason);
});
});
}
Я пытался проверить этот метод с помощью следующего кода:
describe('userService', () => {
let userService: UserService;
let httpClient: HttpTestingController;
const mockedUser = new UserModel();
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [UserService]
});
userService = TestBed.get(UserService);
httpClient = TestBed.get(HttpTestingController);
});
afterEach(() => {
httpClient.verify();
});
it('#login', () => {
const authResponse = {key: '74f0d5ffb992f5f49533d25c686f36414e64482c'};
const response = {username: 'daaaaaaab', email: 'test@test.ir', first_name: 'test', last_name: 'test', phone: '09123657894',
birth_date: '2018-07-31'};
const expectedUser = new UserModel(response.username, response.email, response.first_name, response.last_name, response.phone,
response.birth_date);
userService.login('identifier', 'password').then(user => {
expect(user).toEqual(expectedUser);
expect(userService.user).toEqual(expectedUser);
});
const req = httpClient.expectOne(APIUrlSolver.login); // This response works correct
expect(req.request.method).toBe('POST');
req.flush(JSON.stringify(authResponse));
const userReq = httpClient.expectOne(APIUrlSolver.user); // I get error here
expect(req.request.method).toBe('GET');
userReq.flush(JSON.stringify(response));
});
});
Но этот код всегда будет не работать на userReq
. потому что expectOne
повышает:
Error: Expected one matching request for criteria "Match URL: /user/user/", found none.
Реальный вопрос в том, как я могу проверить эту последовательность HTTP-запросов, потому что HttpClientTestingModule
не работает