0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Cypress API呼び出しテスト

Posted at

〒番号から住所取得できるAPIを呼び出し、Cypressでテストを行ってみた。

〒API:
 https://zipcloud.ibsnet.co.jp/api/search?zipcode=XXXXXXX
  XXXXXXXはqueryparam

方針:
当初は〒APIをフロントエンドから直接呼出しをしようとしていたが、
フロント側からだとCORSエラーになるため、
今後の拡張考えバックエンドから〒APIを呼ぶようにした。

テストについてはフロントエンドからのコンポーネントテストという形で実施。
※今回モックなし。

ソースは以下においてます。
https://github.com/thithi7110/sample-react-cypress

フロント側
npm create-react-app sample-react-cypress --template typescript

cypressのインストール

npm i cypress -D

package.jsonにcypress open追加

package.json
"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "cyopen": "cypress open"
  },
npm run cyopen

を実行し、components設定を追加する。

src/Address.tsx
import React, { useState, useEffect, EventHandler, ChangeEventHandler } from 'react'
import axios from "axios"

type Props = {
    zipcode?: string
    onChange?: (e: string) => void
}
// function AddNum(num1: Number, num2: Number) {
export default function Address(props: Props) {

    const initialState = {
        "zipcode": "",
        "address1": "",
        "address2": "",
        "address3": "",
        "kana1": "",
        "kana2": "",
        "kana3": "",
        "prefcode": "",
    }

    const [zipInfo, setZipInfo] = useState(initialState);

    const getPostInfo = (zipcode: string) => {
        axios.create({
            baseURL: "http://localhost:8085/api",
            headers: {
                "Content-type": "application/json",
            }
        }).get(
            `/zip?zipcode=${zipcode}`
        ).then((res: any) => {
            let inputdata = { ...zipInfo };
            inputdata.address1 = res.data.results[0].address1;
            inputdata.address2 = res.data.results[0].address2;
            inputdata.address3 = res.data.results[0].address3;
            inputdata.kana1 = res.data.results[0].kana1;
            inputdata.kana2 = res.data.results[0].kana2;
            inputdata.kana3 = res.data.results[0].kana3;
            inputdata.prefcode = res.data.results[0].prefcode;
            setZipInfo(inputdata);
        }).catch(e => {
            let error = { ...initialState };
            error.address1 = e;
            setZipInfo(error);

        });
    }

    const onChange = (e: React.ChangeEvent<HTMLInputElement>): void => {

        let inputdata = { ...initialState };
        inputdata.zipcode = e.target.value;
        setZipInfo(inputdata);

        if (e.target.value.length == 7) {
            //API呼び出し
            getPostInfo(e.target.value);
        }
    }

    return (
        <>
            <div>
                <input data-cy='zipcode' value={props.zipcode} onChange={onChange} />
            </div>
            <input data-cy='address1' value={zipInfo.address1} />
            <input data-cy='address2' value={zipInfo.address2} />
            <input data-cy='address3' value={zipInfo.address3} />
            <input data-cy='kana1' value={zipInfo.kana1} />
            <input data-cy='kana2' value={zipInfo.kana2} />
            <input data-cy='kana3' value={zipInfo.kana3} />
            <input data-cy='prefcode' value={zipInfo.prefcode} />
        </>
    );
}


テストコード

cypress/component/Address.cy.tsx
//Adressコンポーネントのテスト
import React, { EventHandler } from 'react'
import Address from '../../src/Address'

describe('住所表示', () => {
    it('Adreesに郵便番号を入力すると郵便番号APIから住所を検索し、郵便番号の下に住所を文字として表示する', () => {
        cy.mount(<Address />)

        cy.get('[data-cy=zipcode]').type('9000025').then(() => {
            cy.get('[data-cy=address1]').should('have.value', "沖縄県");
        })
    })
})

バック側
package.json
{
  "name": "nodejs-express-sequelize-postgresql",
  "version": "1.0.0",
  "description": "Node.js Rest Apis with Express",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "nodejs",
    "express",
    "rest",
    "api"
  ],
  "author": "kenji",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "request": "^2.88.2"
  },
  "devDependencies": {
  }
}

パッケージの取得

npm i

〒APIを呼ぶ箇所
requestで呼び出し

controller.js
// Find a single Tutorial with an id
exports.findzip = (req, res) => {
  var request = require('request');
  
  const pZipCode = req.query.zipcode;

  // クエリーを準備
  const formData = {
    zipcode: pZipCode
  };

  console.log('pZipCode:'+pZipCode);
  
  try{

    request({url:'http://zipcloud.ibsnet.co.jp/api/search', qs:formData}, (error, response, body) => {
      // 実際の処理
      res.send(response.body);
    });  
  }catch(e){
    res.send({error:"error"});
  }  
};
route.js
module.exports = app => {
  const controller = require("../controllers/controller.js");

  var router = require("express").Router();

  router.get("/zip", controller.findzip);

  app.use("/api", router);
};
service.js
const express = require("express");
// const bodyParser = require("body-parser"); /* deprecated */
const cors = require("cors");

const app = express();
//CORS対策
const whitelist = ['http://localhost:8080', 'http://localhost:51401']
var corsOptions = {
  origin: (origin, callback) => {
    console.log(origin);

    callback(null, true)
  }
};

app.use(cors(corsOptions));

// parse requests of content-type - application/json
app.use(express.json());  /* bodyParser.json() is deprecated */

// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));   /* bodyParser.urlencoded() is deprecated */

// simple route
app.get("/", (req, res) => {
  res.json({ message: "Welcome to bezkoder application." });
});

require("./app/routes/routes")(app);

// set port, listen for requests
const PORT = process.env.PORT || 8085;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}.`);
});

テスト実行

フロント側で以下を実行

npm run cyopen

コンポーネントテストのAddress.cy.tsxを選択
実行OK
image.png

フロント側でAPI呼び出しをinterceptする方法を次回試してみる。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?