【问题标题】:how to design microservices with testing in mind如何在考虑测试的情况下设计微服务
【发布时间】:2018-09-18 22:56:25
【问题描述】:

我有一个服务使用cote 库调用另一个服务。我想知道如何设计服务以便于测试。

'use strict';

const logger = require('../../../helper/logger');
const Player = require('../../model/player_model/player_model');
const crypto = require('./../../../helper/crypto_helper');
const cote = require('cote');
let requester = new cote.Requester({name: 'findOnePlayer requester'});

/**
 * Creates new player in database
 * @param username / must be unique
 * @param password
 * @returns {Promise<Player>}
 */
module.exports.createPlayer = async (username, password) => {
  if (!(username && password && username.length && password.length)) {
    throw new Error('Both username and password are required');
  }


  const request = {type: 'findOnePlayer', username: username};
  const existingPlayer = await requester.send(request);

  if (existingPlayer) {
    throw new Error('Username is already taken');
  }


  const password_salt = crypto.genRandomString(16);
  /** Gives us salt of length 16 */
  const password_data = crypto.sha512(password, password_salt);

  const player = new Player({username: username, password_hash: password_data.password_hash, password_salt: password_data.salt});

  // save user
  return await player.save();
};

我想模拟请求者对象的这个方法const existingPlayer = await requester.send(request);。但是 requester 对象被用作 cote 库的构造函数。

对我应该寻找/调查的内容有任何帮助或指导吗?

谢谢

【问题讨论】:

    标签: node.js tdd cote


    【解决方案1】:

    您可以使用 Sinon.js 的 Stubs 来存根请求者的 send() 函数。

    我将通过一个简单的示例进行演示。该文件包含请求者和响应者,并且只返回“bar”。它还导出请求者,因为我们需要访问它才能对它进行存根。

    const cote = require('cote');
    
    // Responder
    const timeService = new cote.Responder({ name: 'Time Service' });
    timeService.on('test', async () => {
        return 'bar'
    });
    
    // Requester
    const requester = new cote.Requester({ name: 'Client' });
    async function test() {
        return requester.send({ type: 'test' })
    }
    
    module.exports = { test, requester } // Export the requester
    

    然后实际测试可以访问请求者并且可以使用 sinons stub(obj, "method")stub.returns('whatever') 函数:

    const test = require('ava')
    const sinon = require('sinon')
    const foo = require('../')
    
    test('test function should return bar when unstubbed and foo when stubbed', async t => {
        // Unstubbed call
        const returnValue = await foo.test()
        t.is(returnValue, 'bar')
        // Stub requester objects send function
        var stub = sinon.stub(foo.requester, "send");
        // Make it return whatever you like
        stub.returns('foo')
        // Test it
        const stubbedValue = await foo.test()
        t.is(stubbedValue, 'foo')
        // Remove the stub
        stub.restore();
        // Original unstubbed call
        const returnValue = await foo.test()
        t.is(returnValue, 'bar')
    });
    

    Check out the docs,您可能还想使用stub.withArgsstub.callsFake(fakeFunction) 使其更灵活。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      • 2011-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多