v2.xでの変更点
Upgrading From Frisby 0.x to 2.x
- Frisby.jsでJasmine Test Frameworkを隠蔽しない
- Jasmine Testの実行環境をjasmine-nodeからJestに変更
- JSON Validatorにjoiを採用
- JSON Schemaは未サポート(使用したい場合はこちらを参照)
細かいところでは…
- HTTP通信をrequestからnode-fetchに変更
- 使用するJavaScriptライブラリをUnderscore.jsからLodashに変更
環境
パッケージ
Frisby.js
https://www.npmjs.com/package/frisby
https://docs.frisbyjs.com/
Jest
https://www.npmjs.com/package/jest
http://facebook.github.io/jest/
環境構築
$ npm install frisby
$ npm install jest
テスト作成
記述
__tests__/*.js
beforeAll(() => {
frisby.globalSetup({
// 共通設定
});
});
describe('Describe', () => {
it('Test', () => {
// FrisbySpecでテストを実施する
return frisby.get('/users/1')
// FrisbySpecでチェーンして色々準備する…
});
});
Frisby
メソッド | |
---|---|
formData() | FormDataを生成する(Multipart用) |
Deplicated |
プロパティ | |
---|---|
version | |
utils | |
Joi | joiを参照する |
Global setup
メソッド | |
---|---|
globalSetup(opts) | 上書き nullを指定すると既定値に戻る |
baseUrl(url) | globalSetup()後に設定する |
opts
{
request: {
credentials: 'include',
headers: {
// 既定値
'Content-Type': 'application/json',
'User-Agent': 'frisby/2.1.2 (+https://github.com/vlucas/frisby)',
},
// baseUrl(既定値:undefined)
baseUrl: undefined,
// rawBody(既定値:false)
rawBody: false,
// inspectOnFailure(既定値:true)
inspectOnFailure: true,
// timeout(既定値:5000[ms])
timeout: 5000,
// redirect('follow'または'manual' 既定値:'follow')
redirect: 'follow',
},
};
FrisbySpec
メソッド | |
---|---|
get() | |
head() | |
options() | |
patch() | |
post() | |
put() | |
delete() | = del() |
fetch() | |
use() | |
setup() | |
timeout() | |
fromJSON() |
FrisbySpecを返却する
Custom Expect Handlers
メソッド | |
---|---|
addExpectHandler(expectName, expectFn) | |
removeExpectHandler(expectName) |
サンプル(HTTPステータスがどれかに一致するかどうか)
const frisby = require('frisby');
beforeAll(() => {
frisby.addExpectHandler('statuses', (response, statuses) => {
if (Array.isArray(statuses)) {
expect(statuses).toContain(response.status);
} else {
expect(response.status).toBe(statuses);
}
});
});
afterAll(() => {
// 必要であれば削除する
frisby.removeExpectHandler('statuses');
});
describe('Custom Expect Handler', () => {
it('Test', () => {
return frisby.get('https://www.google.com')
.expect('statuses', [200, 301])
.expect('statuses', 200);
});
});
サンプル(JSON Schemaによるvalidation)
const frisby = require('frisby');
const Validator = require('jsonschema').Validator; // install jsonschema.
beforeAll(() => {
frisby.addExpectHandler('jsonschema', (response, _path, _schema) => {
let schema = _schema === undefined ? _path : _schema;
let path = _schema === undefined ? false : _path;
frisby.utils.withPath(path, response.json, jsonChunk => {
let validator = new Validator();
validator.validate(jsonChunk, schema, { throwError: true });
});
});
});
afterAll(() => {
// 必要であれば削除する
frisby.removeExpectHandler('jsonschema');
});
describe('Custom Expect Handler', () => {
it('Test1', () => {
return frisby.fromJSON(4)
.expect('jsonschema', { 'type': 'number'});
});
it('Test2', () => {
return frisby.fromJSON([0, 1, 2, 3, 4])
.expect('jsonschema', '*', { 'type': 'number'});
});
});
FrisbySpec
- メソッドはFrisbySpecを返却する(チェーンが可能)
- getterはuse()を使用する
メソッド | |
---|---|
use(fn) | チェーン用 |
setup(opts, replace) | 通常はglobalSetup()で設定する replaceがtrueの場合は上書き |
timeout(timeout) | getter/setter |
getBaseUrl() |
HTTP Requests
メソッド | |
---|---|
get(url, params) | |
head(url, params) | |
options(url, params) | |
patch(url, params) | |
post(url, params) | |
put(url, params) | |
delete(url, params) | = del(url, params) |
fetch(url, params = {}, options = {}) | node-fetch API用 |
fromJSON(json) | ローカル用(jsonで指定した値がResponseとなる) |
HTTP HEADで要求する場合
const frisby = require('frisby');
describe('HTTP method', () => {
it('HEAD', () => {
return frisby.fetch('http://qiita.com/', {
method: 'HEAD',
compress: false,
})
.expect('status', 200);
});
});
HTTP GET(URLパラメーターあり)で要求する場合
const frisby = require('frisby');
describe('HTTP method', () => {
it('GET', () => {
const url = new URL('https://www.google.com/search');
url.searchParams.append('q', 'http://qiita.com/');
return frisby.fetch(url.href, {
method: 'GET',
}, {
urlEncode: false,
})
.expect('status', 200);
});
});
Expectations
メソッド | |
---|---|
expect(expectName) | |
expectNot(expectName) |
expectName | 引数 | |
---|---|---|
status | statusCode | |
header | header, [headerValue] | |
json | [path], json | 指定した値のみを検証 |
jsonStrict | [path], json | すべての値を検証 |
jsonTypes | [path], json | 指定した型のみを検証 |
jsonTypesStrict | [path], json | すべての型を検証 |
bodyContains | value | Bodyがテキストの場合 |
path
- Arrayの要素は数字または角括弧で指定
- pathの値が存在しない場合はError
特殊文字 | |||
---|---|---|---|
* | Array, Object | すべての要素が対象 | = & |
? | Array, Object | どれかひとつの要素が対象 |
Inspectors
メソッド | |
---|---|
inspectRequest() | |
inspectRequestHeaders() | |
inspectResponse() | |
inspectHeaders() | |
inspectStatus() | |
inspectBody() | |
inspectJSON() | |
inspectLog() | 即時出力 |
Promise
メソッド | |
---|---|
then(fn) | |
catch(fn) | |
finally(fn) | |
done(doneFn) | ※最近のトレンドはFrisbySpec(= Promise)を返却する形式 |
promise() | node-fetchのPromiseが返却される |
Tips
Form形式の場合
v2.xはJSON形式が前提(jsonパラメーターがなくなった)だが、以下のようにすることでv.0.8.5から多少の変更で送信が可能
application/x-www-form-urlencoded
const frisby = require('frisby');
const qs = require('qs'); // Jestで入る
describe('application/x-www-form-urlencoded', () => {
it('Test', () => {
return frisby.post('/login', {
body: qs.stringify({
id: 'testy.mctesterpants@example.com',
password: 'frisbbbbbbbbbby',
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
})
.expect('status', 200);
});
});
multipart/form-data
const frisby = require('frisby');
describe('multipart/form-data', () => {
it('Test', () => {
let form = frisby.formData();
form.append('id', 'testy.mctesterpants@example.com');
form.append('password', 'frisbbbbbbbbbby');
return frisby.post('/login', {
body: form
})
.expect('status', 200);
});
});
Basic認証
user: user, password: passwd
const frisby = require('frisby');
const url = require('url');
it('auth test(2)', () => {
// use Legacy URL API.
let myURL = url.parse('https://httpbin.org/basic-auth/user/passwd');
myURL.auth = 'user:passwd';
return frisby.get(url.format(myURL))
.expect('status', 200);
});
バイナリのテスト
PNG解析
const frisby = require('frisby');
it('PNG test', () => {
return frisby.setup({ request: { rawBody: true } })
.get('https://httpbin.org/image/png')
.expect('status', 200)
.expect('header', 'Content-Type', 'image/png')
.then(res => {
let body = res.body;
expect(body.byteLength).toBeGreaterThan(8);
expect(String.fromCharCode.apply(null, new Uint8Array(body.slice(1, 4)))).toEqual('PNG');
});
});
テスト実施
準備
package.json
{
"scripts": {
"test": "jest"
}
}
オプション
Configuring Jest
実行
- すべて実行する場合
$ npm test
- ファイルを指定して実行する場合
$ npm test -- __tests__/xxx.spec.js
※Windows(Git Bash)でファイル名を指定して実行する場合のメモ
$ npm test -- __tests__\\\\xxx.spec.js