簡體   English   中英

僅使用 Mocha 在單元測試中模擬調用 Typescript

[英]Mock call in Typescript in unit test using only Mocha

我有以下方法:

import { ObjectDal } from "./ObjectDal";

export class ObjectBL {
  async getObject(id) {
      try {
          let dal = new ObjectDal();

          let result = await dal.get(id);

          return result;

      } catch (err) {
          // log the error
      }
}

ObjectDal類是:

export class ObjectDal {
    async get(id) {
        // open connection to db
        // make a query based on id

        // put the result in a `result` variable

        return result;
    }
}

我必須使用 Mocha 為getObject()方法編寫單元測試...

這是UT的開始:

const assert = require('assert');
const ObjectBL = require("../ObjectBL");

describe('Something', () => {
    describe('...', () => {
        it('getObject_GetsObjectUsingID_True', async () => {
            // arange
            let id = "123456789101";
            let expected = {
                "name": "ana",
                "hasApples": true
            };

            let test = new ObjectBL.ObjectBL();

            let result = await test.getObject(id);

            assert.deepStrictEqual(result, expected);
        });
    });
});

但在這種情況下,我將不得不從ObjectDal類調用該方法......

如何僅使用 Mocha 模擬對get()方法的調用?

我用詩濃找到了答案,或者用詩濃和/或柴找到了摩卡......但只有摩卡沒有......

代理可能是您的最佳選擇。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

您可以使用代理來模擬方法,如下所示:

 const assert = require('assert'); const ObjectBL = require("../ObjectBL"); describe('Something', () => { describe('...', () => { it('getObject_GetsObjectUsingID_True', async () => { // arange let id = "123456789101"; let expected = { "name": "ana", "hasApples": true }; let test = new ObjectBL.ObjectBL(); const handler = { get: function(obj, prop) { // mok the getObject method if(prop === 'getObject'){ return () => { return Promise.resolve({ "name": "ana", "hasApples": true }); } } else { return obj[prop]; } } }; const p = new Proxy(test, handler); let result = await p.getObject(id); assert.deepStrictEqual(result, expected); }); }); });

如果您只想使用ObjectDal.get方法,您可能需要覆蓋原型並在之后恢復它:

 const assert = require('assert'); const ObjectBL = require("../ObjectBL"); const ObjectDal = require("../ObjectDal"); describe('Something', () => { describe('...', () => { it('getObject_GetsObjectUsingID_True', async () => { // arange let id = "123456789101"; let expected = { "name": "ana", "hasApples": true, }; const proto = Object.getOwnPropertyDescriptor(ObjectDal, 'prototype').value; const backup = proto.get; proto.get = () => { return Promise.resolve({ "name": "ana", "hasApples": true, }); } let test = new ObjectBL.ObjectBL(); let result = await test.getObject(id); ObjectDal.prototype.get = backup; assert.deepStrictEqual(result, expected); }); }); });

您還可以使用代理覆蓋ObjectDal並實現construct處理程序以返回一個虛擬的ObjectDal ,但這可能更棘手,因為您正在使用模塊。

測試是反饋,不僅僅是關於你的代碼是否像宣傳的那樣工作,而且更重要的是你的設計質量

您在編寫測試時遇到問題的事實是您在實現中做了一些次優的事情的第一個跡象。 你想要的是這個

export class ObjectBL {
  constructor (dal) {
      this.dal = dal;
  }

  async getObject(id) {
      try {
          let result = await this.dal.get(id);

          return result;

      } catch (err) {
          // log the error
      }
}

...現在依賴是明確的而不是隱含的,並將顯示在編輯器工具提示中,更適合靜態分析等。它解決了你的問題:現在你可以輕松地模擬它進行測試,不需要更多的庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM