TS‐Jestによるマングースの試験


あなたがマングースでMongoDBを学びたいならば、テストによる学習はあなたのためだけです.このブログの記事では、Tet - Jestをインストールする方法と、typescriptと@ faker js/fakerを使ってモデルや偽データを作成する方法と、それらをテストするためにJestを使う方法について話します.

なぜテストが重要ですか?


我々が書いたコードをテストすることは、将来起こる可能性のある問題に気づいたり、コードの振る舞いについての考えを与えたりする.例えば、私たちには車のモデルがあります、そして、自動車モデルは年齢という名前のフィールドを持ちます.年齢フィールドは負ではありません.この時点で、我々は年齢が負の値であるときに何が起こるかを確認する必要があります.車のモデルに年齢フィールドの負の入力を与えると、自動車モデルは、テストモジュールでエラーをスローすると予想します.したがって、自動車モデルがプロジェクトを展開する前に目的に沿って動くならば、我々は確実でありえます.

どのような冗談ですか?


Jest JavaScriptのテストフレームワークです.Jestを使用してすべてのモデルをテストします.JESTフレームワークを使用する理由は、テストの最小設定が必要です.

プロジェクトの作成とパッケージのインストール


パッケージの作成JSON
npm init -y
このブログの中でTS Jestパッケージを使用しますts-jest タイプスクリプトで書かれたプロジェクトをテストするために、Jestを使用します.
パッケージのインストール
npm install -D jest typescript ts-jest @types/jest ts-node @types/node
Mongooseをインストールしている間、MoodOseパッケージがビルトインタイプスクリプト宣言を持っているので、@ types/mongooseを必要としません.
npm install mongoose
私自身で入力にデータを与えることは難しいですfaker js/fakerはモデルのランダムデータを作成するのに役立ちます.
npm install -D @faker-js/faker
TSconfigの作成JSON
tsc --init
TSconfigでプロパティを変更します.JSONプロジェクト
 "rootDir": "./src",
 "moduleResolution": "node",
 "baseUrl": ".",
 "outDir": "./build",
TSCONFIGでのincludeとexcludeの追加.JSON
"include": ["src/**/*.ts"],
"exclude": ["node_modules","build"]

テスト用の設定ファイルの作成


npx ts-jest config:init
その後、冗談を見ることができました.設定.プロジェクトフォルダ内のjs.そしてそれです.我々は行く準備ができている.

プロジェクト構造


私はこのプロジェクトを本当のものとして受け入れるので、srcとtestという2つのメインフォルダを作ります.モデルファイルはSRCのモデルフォルダにありますが、モデルのテストはテストになります.

MongoDBの接続


ConnectDBForestを作成します.テストフォルダーのTS.あなたがMongoDBに接続している間、あなたが接続オプションを加えるか、変えるかもしれない異なるオプションがあるならば、私のMongoDBはLocalhostで動きます.
touch test/connectDBForTesting.ts
テスト/connectDBForestテスト.TS
import mongoose from "mongoose";

export async function connectDBForTesting() {
  try {
    const dbUri = "mongodb://localhost:27018";
    const dbName = "test";
    await mongoose.connect(dbUri, {
      dbName,
      autoCreate: true,
    });
  } catch (error) {
    console.log("DB connect error");
  }
}

export async function disconnectDBForTesting() {
  try {
    await mongoose.connection.close();
  } catch (error) {
    console.log("DB disconnect error");
  }
}

マングースモデルの作成


マングースのモデルは、MongoDBデータベースから作成、読み取り、削除、およびドキュメントを更新するために使用されます.人モデルをつくって、テストしましょう.
touch src/models/person.model.ts
src/model/personモデル.TS
import mongoose, { Types, Schema, Document } from "mongoose";

export interface PersonInput {
  name: string;
  lastName: string;
  address: string;
  gender: string;
  job: string;
  age: number;
}

export interface PersonDocument extends PersonInput, Document {
  updatedAt: Date;
  createdAt: Date;
}

const PersonSchema = new mongoose.Schema<PersonDocument>(
  {
    name: { type: String, required: [true, "name required"] },
    lastName: { type: String },
    address: { type: String, required: [true, "address required"] },
    gender: { type: String, required: [true, "gender is required"] },
    job: { type: String },
    age: { type: Number, min: [18, "age must be adult"] },
  },
  {
    timestamps: true, // to create updatedAt and createdAt
  }
);

const personModel = mongoose.model("Person", PersonSchema);
export default personModel;
ここで2つの重要なことがありますPersonDocument インタフェースpersonInputインターフェイスは、personModelを作成するために使用され、PersonDocumentインターフェイスは、PersonModelによって返されるオブジェクトについて説明します.PersonModelのテストセクションで明確に表示されます.

PersonModelのテストの作成


touch test/person.model.test.ts
テスト/人.モデル.テスト.TS
import {
  connectDBForTesting,
  disconnectDBForTesting,
} from "../connectDBForTesting";

import personModel, {
  PersonDocument,
  PersonInput,
} from "../../src/models/person.model";
import faker from "@faker-js/faker";
describe("personModel Testing", () => {
  beforeAll(async () => {
    await connectDBForTesting();
  });

  afterAll(async () => {
    await personModel.collection.drop();
    await disconnectDBForTesting();
  });
});
まず第一にdescribe テストセクションを含むブロックを作成します.記述ブロック内にいくつかのグローバルオブジェクトを追加して使用できます.
beforeAll 説明ブロック内のすべてのテストが実行される前に関数を実行します.前もって、MongoDBサーバを接続します.
afterAll 記述ブロック内のすべてのテストが補完された後に関数を実行します.結局、MongoDBサーバーを切断し、PersonModelコレクションを削除します.

テストを作成する


test("personModel Create Test", async () => {
  const personInput: PersonInput = {
    name: faker.name.findName(),
    lastName: faker.name.lastName(),
    age: faker.datatype.number({ min: 18, max: 50 }),
    address: faker.address.streetAddress(),
    gender: faker.name.gender(),
    job: faker.name.jobTitle(),
  };
  const person = new personModel({ ...personInput });
  const createdPerson = await person.save();
  expect(createdPerson).toBeDefined();
  expect(createdPerson.name).toBe(person.name);
  expect(createdPerson.lastName).toBe(person.lastName);
  expect(createdPerson.age).toBe(person.age);
  expect(createdPerson.address).toBe(person.address);
  expect(createdPerson.gender).toBe(person.gender);
  expect(createdPerson.job).toBe(person.job);
});
注意:新しいpersonModelが宣言されたときは、PersonDocument型オブジェクトを返します.それで、私はマングースを使うことができます.ドキュメントのプロパティ、検証、およびミドルウェア.
PersonInputを使ってpersonオブジェクトを作成します.人.save ()メソッドは、新しいドキュメントをデータベースに挿入し、personDocument型オブジェクトを返します.
expect 指定したデータがある条件に一致するかどうかを調べます.与えられたデータがある条件にマッチするならば、テストは通過します.そうでなければテストは失敗する.

テスト/モデル/人の最後の状態。モデル.テスト。TS


import {
  connectDBForTesting,
  disconnectDBForTesting,
} from "../connectDBForTesting";

import personModel, {
  PersonDocument,
  PersonInput,
} from "../../src/models/person.model";
import faker from "@faker-js/faker";
describe("personModel Testing", () => {
  beforeAll(async () => {
    await connectDBForTesting();
  });
  afterAll(async () => {
    await personModel.collection.drop();
    await disconnectDBForTesting();
  });

  test("personModel Create Test", async () => {
    const personInput: PersonInput = {
      name: faker.name.findName(),
      lastName: faker.name.lastName(),
      age: faker.datatype.number({ min: 18, max: 50 }),
      address: faker.address.streetAddress(),
      gender: faker.name.gender(),
      job: faker.name.jobTitle(),
    };
    const person = new personModel({ ...personInput });
    const createdPerson = await person.save();
    expect(createdPerson).toBeDefined();
    expect(createdPerson.name).toBe(person.name);
    expect(createdPerson.lastName).toBe(person.lastName);
    expect(createdPerson.age).toBe(person.age);
    expect(createdPerson.address).toBe(person.address);
    expect(createdPerson.gender).toBe(person.gender);
    expect(createdPerson.job).toBe(person.job);
  });
});

冗談を実行する


私は、パッケージのスクリプトにコマンドを加えます.ジェンソンを走らせるJSON.
"scripts": {
    "test": "npx jest --coverage "
  },
coverage オプションは、テスト範囲情報を収集し、出力に報告する必要があることを示します.しかし、あなたはそれを無視することができます.
私はテストを実行します.
npm run test
試験結果

テストが失敗したときに何が起こるかを見るために、予期しない側を間違ったデータで変更します.
expect(createdPerson.job).toBe(person.name);
テスト失敗の結果

テストが失敗した理由は、JESTが作成したものを想定していることです.仕事と創造者.同じデータを持つ名前.

読込テスト


test("personModel Read Test", async () => {
  const personInput: PersonInput = {
    name: faker.name.findName(),
    lastName: faker.name.lastName(),
    age: faker.datatype.number({ min: 18, max: 50 }),
    address: faker.address.streetAddress(),
    gender: faker.name.gender(),
    job: faker.name.jobTitle(),
  };
  const person = new personModel({ ...personInput });
  await person.save();
  const fetchedPerson = await personModel.findOne({ _id: person._id });
  expect(fetchedPerson).toBeDefined();
  expect(fetchedPerson).toMatchObject(personInput);
});
私は、personmodelをつくって、それを保存して、人をRicidによって取得させます.fetchPersonプロパティが期待を使用してpersonInputプロパティに一致するかどうかを確認できます.expect ()を使用します.TomatochObject ()は少し簡単です.
expect.toMatchObject() 受信JavaScriptオブジェクトが予想されるJavaScriptオブジェクトのプロパティに一致するかどうかを調べます.

行方不明


各テストのために、私は何度も何度も人モデルをつくりました.これはあまり効率的ではなかったので、personInputとPersonModelのトップを記述します.
describe("personModel Testing", () => {}
const personInput: PersonInput = {
    name: faker.name.findName(),
    lastName: faker.name.lastName(),
    age: faker.datatype.number({ min: 18, max: 50 }),
    address: faker.address.streetAddress(),
    gender: faker.name.gender(),
    job: faker.name.jobTitle(),
  };
  const person = new personModel({ ...personInput });
)
したがって、すべてのテストでPersonInputとPersonオブジェクトを使用できます.

PersonModel更新テスト


test("personModel Update Test", async () => {
  const personUpdateInput: PersonInput = {
    name: faker.name.findName(),
    lastName: faker.name.lastName(),
    age: faker.datatype.number({ min: 18, max: 50 }),
    address: faker.address.streetAddress(),
    gender: faker.name.gender(),
    job: faker.name.jobTitle(),
  };
  await personModel.updateOne({ _id: person._id }, { ...personUpdateInput });
  const fetchedPerson = await personModel.findOne({ _id: person._id });
  expect(fetchedPerson).toBeDefined();
  expect(fetchedPerson).toMatchObject(personUpdateInput);
  expect(fetchedPerson).not.toMatchObject(personInput);
});
同じスキーマを使用しても、@ faker js/fakerがランダムにデータを作成するので、personinputとは異なるpersonupdateinputを作成できます.fetchedPersonのプロパティは、PersonUpdateInputに一致すると予想されます.

削除テスト


test("personModel Delete Test", async () => {
  await personModel.deleteOne({ _id: person._id });
  const fetchedPerson = await personModel.findOne({ _id: person._id });
  expect(fetchedPerson).toBeNull();
});
人を使ってマングース文書を削除この後、MongoDBから取得したFETCHEDはNULLであることが期待されます.

テスト/モデル/人の最後の状態。モデル.テスト。TS


import {
  connectDBForTesting,
  disconnectDBForTesting,
} from "../connectDBForTesting";

import personModel, {
  PersonDocument,
  PersonInput,
} from "../../src/models/person.model";
import faker from "@faker-js/faker";
describe("personModel Testing", () => {
  const personInput: PersonInput = {
    name: faker.name.findName(),
    lastName: faker.name.lastName(),
    age: faker.datatype.number({ min: 18, max: 50 }),
    address: faker.address.streetAddress(),
    gender: faker.name.gender(),
    job: faker.name.jobTitle(),
  };
  const person = new personModel({ ...personInput });

  beforeAll(async () => {
    await connectDBForTesting();
  });
  afterAll(async () => {
    await personModel.collection.drop();
    await disconnectDBForTesting();
  });

  test("personModel Create Test", async () => {
    const createdPerson = await person.save();
    expect(createdPerson).toBeDefined();
    expect(createdPerson.name).toBe(person.name);
    expect(createdPerson.lastName).toBe(person.lastName);
    expect(createdPerson.age).toBe(person.age);
    expect(createdPerson.address).toBe(person.address);
    expect(createdPerson.gender).toBe(person.gender);
    expect(createdPerson.job).toBe(person.job);
  });

  test("personModel Read Test", async () => {
    const fetchedPerson = await personModel.findOne({ _id: person._id });
    expect(fetchedPerson).toBeDefined();
    expect(fetchedPerson).toMatchObject(personInput);
  });
  test("personModel Update Test", async () => {
    const personUpdateInput: PersonInput = {
      name: faker.name.findName(),
      lastName: faker.name.lastName(),
      age: faker.datatype.number({ min: 18, max: 50 }),
      address: faker.address.streetAddress(),
      gender: faker.name.gender(),
      job: faker.name.jobTitle(),
    };
    await personModel.updateOne({ _id: person._id }, { ...personUpdateInput });
    const fetchedPerson = await personModel.findOne({ _id: person._id });
    expect(fetchedPerson).toBeDefined();
    expect(fetchedPerson).toMatchObject(personUpdateInput);
    expect(fetchedPerson).not.toMatchObject(personInput);
  });

  test("personModel Delete Test", async () => {
    await personModel.deleteOne({ _id: person._id });
    const fetchedPerson = await personModel.findOne({ _id: person._id });
    expect(fetchedPerson).toBeNull();
  });
});

テスト


npm run test

結果



それです.これは通常、マングースモデルをテストする方法です.
  • マングースモデルを作成します.
  • マングースモデルのテストを作成します.
  • テストセクションのマングースモデルのCRUD操作を適用します.
  • テストが失敗したら、問題を見つけて解決してみてください.
  • すべてのテストが通るならば、あなたは行く準備ができています.
  • ソース
  • https://jestjs.io/docs/getting-started

  • https://mongoosejs.com/docs/guide.html
  • https://kulshekhar.github.io/ts-jest/
  • 私に連絡してください
  • github
  • ギタブレポhttps://github.com/pandashavenobugs/testing-mongoose-with-tsjest-blogpost