「入門Node.jsプログラミング 」の感想・備忘録12

スポンサーリンク
「入門Node.jsプログラミング 」の感想・備忘録11の続き

Lesson30

socket.ioを使う

  • リアルタイム更新を行うためには、以下の方法がある。
    • 繰り返しリクエストを発行する(ポーリング)
    • Webソケットを使う
  • Webソケットは新しいブラウザしか対応していない。
  • socket.ioパッケージはWebソケットを使うが、対応していない場合はポーリングを使う。
    npm install socket.io
const server = app.listen(app.get('port'), () => {
  console.log(`Server running at http://localhost:${app.get('port')}`);
});
const io = require("socket.io")(server);
require("./controllers/chatController")(io);
"use strict";

module.exports = io => {
  io.on("connection", client => {
    console.log("new connection");
    client.on("disconnect", () => {
      console.log("user disconnected");
    });
    // カスタムイベントの定義
    client.on("message", data => {
      // 接続中の全ユーザーに送信
      io.emit("message", {
        content: data.content
      });
    });
  });
};
<script src="/socket.io/socket.io.js"></script>
<form id="chatForm">
  <input id="msg" type="text">
  <input type="submit" class="button" value="Send">
</form>
<div id="chat"></div>
<script>
const socket = io();
document.getElementById("chatForm").onsubmit = () => {
  socket.emit("message", {content: document.getElementById('msg').value});
  document.getElementById("msg").value = '';
  return false;
};

socket.on("message", message => {
  let p = document.createElement("p");
  p.innerHTML = message.content;
  document.getElementById('chat').prepend(p);
});
</script>

Lesson35

デバッグ

デバッグモード

  • DEBUG=* node indexで実行すると、経路登録などの細かいログも出力される。

ステップ実行

  • node inspect tindexで実行するとステップ実行となる。
  • nで次の行に進み、cで連続実行。 replでREPLモードとなり、変数などを調べることがきる。
  • ソースにdebugger;を埋め込むとブレークポイントとなる。
  • ただし、この方法でのデバッグは時間がかかるので、node-inspecotなどを使ってChromeコンソールでデバッグする方がよい。

morganパッケージ

  • 本番環境の場合はmorganパッケージを使うと良い。
  • npm install morgan
const morgan = require('morgan');
// 以下でフォーマット指定
app.use(morgan(':method :url :status * :response-time ms'));
// または
app.use(morgan('combined'));

Lesson36

mochaとchaiで行うテスト

  • npm install mocha chai --save-dev
  • npx mochaで実行
"use strict";

const getUserParams = body => {
  return {
    name: body.name,
    email: body.email,
    password: body.password,
    zipCode: body.zipCode
  };
};

module.exports = {
  getUserParams
};
"use strict";

const chai = require("chai"),
  {expect} = chai,
  usersController = require("../controllers/usersController");

describe("usersController", () => {
  describe("getUserParams", () => {
    it("should convert request body to contain the name attributes of the user object", () => {
      const body = {
        name: "Jon",
        email: "jon@jonwexler.com",
        password: 12345,
        zipCode: 10016
      };
      expect(usersController.getUserParams(body)).to.deep.include({
        name: "Jon",
        email: "jon@jonwexler.com",
      });
    });

    it("should return an empty object with empty request body input", () => {
      const emptyBody = {};
      expect(usersController.getUserParams(emptyBody)).to.deep.include({});
    });
  });
});

環境変数でテスト環境に切り替える

if (process.env.NODE_ENV === "test") {
  mongoose.connect(
    "mongodb://localhost:27017/recipe_test_db",
    { useNewUrlParser: true }
  );
  app.set("port", 3001);
} else {
  mongoose.connect(
    process.env.MONGODB_URI || "mongodb://localhost:27017/recipe_db",
    { useNewUrlParser: true }
  );
  app.set("port", process.env.PORT || 3000);
}
// 末尾に以下を記述して、テストファイルからappにアクセスできるようにする
module.exports = app;
// 先頭に記述
process.env.NODE_ENV = 'test';
// appへのアクセスが必要な場合
app = require("../index");

WEBアプリのテスト

  • npm install chai-http --save-dev

モデルのテスト

"use strict";

process.env.NODE_ENV = 'test';
const User = require( '../models/user' ),
  { expect } = require( 'chai' );
require("../index");

beforeEach( done => {
  User.remove( {} )
    .then( () => {
      done();
    } );
} );

describe( 'SAVE user', () => {
  it( 'it should save one user', ( done ) => {
    let testUser = new User( {
      name: 'Jon',
      email: 'Jon@jonwexler.com',
      password: 12345,
      zipCode: 10016,
      apiToken: '12345678901234567890123456789012'
    } );
    testUser.save()
      .then( () => {
        User.find( {} )
          .then( result => {
            expect( result.length )
              .to.eq( 1 );
            expect( result[ 0 ] )
              .to.have.property( '_id' );
            done()
          } );
      } );
  } );
} );

コントローラのテスト

"use strict";

const chai = require("chai"),
  {expect} = chai,
  chaiHTTP = require("chai-http"),
  app = require("../index");

chai.use(chaiHTTP);
describe("usersController", () => {
  describe("/users GET", () => {
    it("it should GET all the users", done => {
      chai
        .request(app)
        .get("/users")
        .end((errors, res) => {
          expect(res).to.have.status(200);
          expect(errors).to.be.equal(null);
          done();
        });
    });
  });
});

コメント