LoginSignup
3
5

More than 5 years have passed since last update.

Mocha+Sinon.JSでjQueryのajaxコールを、XMLHttpRequestを置き換えてテストする。

Last updated at Posted at 2017-06-26

概要

前回のMocha+Sinon.JSでjQueryのget, ajaxをスタブに置き換えてテストする。 - Qiitaでは、Sinon.JSのstubを使って、
$.get$.ajaxのコールバックを置き換えることでテストしました。

本記事では、jQueryの$.get, $.ajaxが内部で使っているXMLHttpRequestを置き換えることで、
$.postなどに対しても置き換えを行います。

環境

macOS Sierra 10.12.5
Docker for Mac 17.03.1-ce-mac12 (17661)

準備

前回同様にDocker上で環境構築します。

テスト実行!

docker.shの中にdockerコンテナ内でmochaを起動するスクリプトを入れておいたので、それを使います。

$ ./docker.sh mocha opt/fake.js

こんな感じのメッセージが出力されるはずです。

  Test User API
    ✓ get /api/users/100


  1 passing (45ms)

解説

Dockerコンテナ内の環境について

Dockerfile

Dockerfileは前回同様です。

docker.sh

前回からの変更点です。

docker.sh
"mocha" )
    TARGET=`echo $2 | sed 's/^opt\///'`
    shift
    shift

    docker run \
      --rm \
      --name ${SERVICE_NAME} \
      -v "$(pwd)"/opt:/opt \
      ${REPO}:${TAG} \
      mocha ${TARGET} $@
    exit
    ;;

$ ./docker.sh mocha optまで入力したところでTABを押すとbash であればファイルリストが表示されます。
そのまま、ローカルのファイルを$ ./docker.sh mocha opt/fake.jsという形で指定すると、
TARGETの行にあるように、opt/を外すことでコンテナ内のパスに置き換えてくれます。

テストコード

今回のテストコードです。

fake.js
// Sinon.JS初期化
var sinon = require('sinon');
var assert = require('assert');

// windowオブジェクト生成
var jsdom = require('jsdom/lib/old-api.js');
global.window = jsdom.jsdom().defaultView;

// jQuery初期化
var $ = require('jquery');


/**
 * User APIのテスト
 */
describe('Test User API', function () {

    var server;
    var spy;

    /**
     * before test
     */
    before(() => {
        // sinon Fake Server生成
        server = sinon.fakeServer.create();

        // XMLHttpRequest置き換え
        global.window.XMLHttpRequest = server.xhr;

        // Sinon Spy初期化
        spy = sinon.spy();
    });

    /**
     * after test
     */
    after(() => {
        server.restore();
    });

    /**
     * $.getのテスト
     */
    it("get /api/users/100", () => {
        // Initialize
        var response = {
            id: 100,
            name: "teruchi"
        };

        // Test
        $.getJSON('/api/users/100', spy);


        server.respond(
            'GET',
            '/api/users/100',
            [
                200,
                {
                    'Content-Type': 'application/json'
                },
                JSON.stringify(response)
            ]
        );

        // Assertions
        assert(spy.calledOnce);

        assert(spy.calledWith(response));
    });
});

前回うまくいかなかったと書きましたが、
globalXMLHttpRequestを、
sinon.fakeServerxhrに置き換えることで動くようになりました。

あとがき

普段、PHPUnitを使っている身としては、sinon.stubの方がテストを考えやすい場面が多いですが、
APIの実装を記述しながらのテストコードの方がわかりやすい場面もあると思います。
場面によって使い分けるといいと思いました。

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5