繁体   English   中英

在Node.js的模拟函数中跟踪调用链

[英]Track call chain from within mock functions in Node.js

我需要编写一个自动测试,该测试应跟踪函数调用链。 在下面的示例中,这些函数称为nativefn1nativefn2 我无法更改其代码以使跟踪成为可能,因此我需要针对这种情况的一些解决方法。

var async = require('async')

nativefn1 = function(input, cb) {
  setTimeout(
    function() { cb(null,"<" + input + ">") },
    Math.floor(Math.random() * 1000)
  )
}

nativefn2 = function(input, cb) {
  setTimeout(
    function() { nativefn1(input, function(err,result) { cb(null,"<<" + result + ">>") } ) },
    Math.floor(Math.random() * 1000)
  )
}

var callchain_counter = 0
var debug_results = { "???": [] }
var original = {
  nativefn1: nativefn1,
  nativefn2: nativefn2,
}

nativefn2 = function(input, cb) {
  var callchain_number = callchain_counter++
  debug_results[callchain_number] = []
  debug_results[callchain_number].push("Callchain #" + callchain_number + ": nativefn2 call:", arguments)
  original.nativefn2(input,function(err,result) {
    debug_results[callchain_number].push("Callchain #" + callchain_number + ": nativefn2 call result:", arguments)
    cb(null,result)
  })
}

nativefn1 = function(input, cb) {
  var callchain_number = "???"
  debug_results[callchain_number].push("Callchain #" + callchain_number + ": nativefn1 call:", arguments)
  original.nativefn1(input,function(err,result) {
    debug_results[callchain_number].push("Callchain #" + callchain_number + ": nativefn1 call result:", arguments)
    cb(null,result)
  })
}

async.parallel(
  [
    function(done) { nativefn2("Lorem",done) },
    function(done) { nativefn2("ipsum",done) },
    function(done) { nativefn2("dolor",done) },
    function(done) { nativefn2("amet",done) },
    function(done) { nativefn2("sit",done) },
  ],
  function(err,result) {
    console.log(debug_results)
  }
)

执行后,此代码将debug_results如下debug_results

{ '0': 
   [ 'Callchain #0: nativefn2 call:',
     { '0': 'Lorem', '1': [Function] },
     'Callchain #0: nativefn2 call result:',
     { '0': null, '1': '<<<Lorem>>>' } ],
  '1': 
   [ 'Callchain #1: nativefn2 call:',
     { '0': 'ipsum', '1': [Function] },
     'Callchain #1: nativefn2 call result:',
     { '0': null, '1': '<<<ipsum>>>' } ],
  '2': 
   [ 'Callchain #2: nativefn2 call:',
     { '0': 'dolor', '1': [Function] },
     'Callchain #2: nativefn2 call result:',
     { '0': null, '1': '<<<dolor>>>' } ],
  '3': 
   [ 'Callchain #3: nativefn2 call:',
     { '0': 'amet', '1': [Function] },
     'Callchain #3: nativefn2 call result:',
     { '0': null, '1': '<<<amet>>>' } ],
  '4': 
   [ 'Callchain #4: nativefn2 call:',
     { '0': 'sit', '1': [Function] },
     'Callchain #4: nativefn2 call result:',
     { '0': null, '1': '<<<sit>>>' } ],
  '???': 
   [ 'Callchain #???: nativefn1 call:',
     { '0': 'ipsum', '1': [Function] },
     'Callchain #???: nativefn1 call result:',
     { '0': null, '1': '<ipsum>' },
     'Callchain #???: nativefn1 call:',
     { '0': 'Lorem', '1': [Function] },
     'Callchain #???: nativefn1 call:',
     { '0': 'amet', '1': [Function] },
     'Callchain #???: nativefn1 call:',
     { '0': 'dolor', '1': [Function] },
     'Callchain #???: nativefn1 call:',
     { '0': 'sit', '1': [Function] },
     'Callchain #???: nativefn1 call result:',
     { '0': null, '1': '<Lorem>' },
     'Callchain #???: nativefn1 call result:',
     { '0': null, '1': '<amet>' },
     'Callchain #???: nativefn1 call result:',
     { '0': null, '1': '<dolor>' },
     'Callchain #???: nativefn1 call result:',
     { '0': null, '1': '<sit>' } ] }

但是所有nativefn1调用都无法跟踪,因为我找不到将callchain_numbernativefn2nativefn1 是否可以通过某种方式访问​​调用上下文或创建一些其他调用上下文以使其成为可能? 函数必须并行调用。

我发现可以使用域来完成此操作,但是由于不建议使用域,所以我想知道应该用什么替换它们。

var async = require('async')
var domain = require('domain')

nativefn1 = function(input, cb) 
{
    setTimeout(
        function() { cb(null,"<" + input + ">") },
        Math.floor(Math.random() * 1000)
    )
}

nativefn2 = function(input, cb) 
{
    setTimeout(
        function() { nativefn1(input, function(err,result) { cb(null,"<<" + result + ">>") } ) },
        Math.floor(Math.random() * 1000)
    )
}

var context_counter = 0
var callchain_counter = 0
var debug_results = {}
var original = 
{
    nativefn1: nativefn1,
    nativefn2: nativefn2,
}

nativefn2 = function(input, cb) 
{
    var d = domain.create()
    var args = arguments
    d.callchain_number = callchain_counter++
    d.run(function()
    {
        debug_results[domain.active.callchain_number] = []
        debug_results[domain.active.callchain_number].push("Callchain #" + domain.active.callchain_number + ": nativefn2 call:", args)
        original.nativefn2(input,function(err,result) 
        {
            debug_results[domain.active.callchain_number].push("Callchain #" + domain.active.callchain_number + " nativefn2 call result:", arguments)
            cb(null,result)
        })
    })
}

nativefn1 = function(input, cb) 
{
    debug_results[domain.active.callchain_number].push("Callchain #" + domain.active.callchain_number + ": nativefn1 call:", arguments)
    original.nativefn1(input,function(err,result) 
    {
        debug_results[domain.active.callchain_number].push("Callchain #" + domain.active.callchain_number + ": nativefn1 call result:", arguments)    
        cb(null,result)
    })
}

async.parallel(
  [
    function(done) { nativefn2("Lorem",done) },
    function(done) { nativefn2("ipsum",done) },
    function(done) { nativefn2("dolor",done) },
    function(done) { nativefn2("amet",done) },
    function(done) { nativefn2("sit",done) },
  ],
  function(err,result) {
    console.log(debug_results)
  }
)

输出:

{ '0': 
   [ 'Callchain #0: nativefn2 call:',
     { '0': 'Lorem', '1': [Function] },
     'Callchain #0: nativefn1 call:',
     { '0': 'Lorem', '1': [Function] },
     'Callchain #0: nativefn1 call result:',
     { '0': null, '1': '<Lorem>' },
     'Callchain #0 nativefn2 call result:',
     { '0': null, '1': '<<<Lorem>>>' } ],
  '1': 
   [ 'Callchain #1: nativefn2 call:',
     { '0': 'ipsum', '1': [Function] },
     'Callchain #1: nativefn1 call:',
     { '0': 'ipsum', '1': [Function] },
     'Callchain #1: nativefn1 call result:',
     { '0': null, '1': '<ipsum>' },
     'Callchain #1 nativefn2 call result:',
     { '0': null, '1': '<<<ipsum>>>' } ],
  '2': 
   [ 'Callchain #2: nativefn2 call:',
     { '0': 'dolor', '1': [Function] },
     'Callchain #2: nativefn1 call:',
     { '0': 'dolor', '1': [Function] },
     'Callchain #2: nativefn1 call result:',
     { '0': null, '1': '<dolor>' },
     'Callchain #2 nativefn2 call result:',
     { '0': null, '1': '<<<dolor>>>' } ],
  '3': 
   [ 'Callchain #3: nativefn2 call:',
     { '0': 'amet', '1': [Function] },
     'Callchain #3: nativefn1 call:',
     { '0': 'amet', '1': [Function] },
     'Callchain #3: nativefn1 call result:',
     { '0': null, '1': '<amet>' },
     'Callchain #3 nativefn2 call result:',
     { '0': null, '1': '<<<amet>>>' } ],
  '4': 
   [ 'Callchain #4: nativefn2 call:',
     { '0': 'sit', '1': [Function] },
     'Callchain #4: nativefn1 call:',
     { '0': 'sit', '1': [Function] },
     'Callchain #4: nativefn1 call result:',
     { '0': null, '1': '<sit>' },
     'Callchain #4 nativefn2 call result:',
     { '0': null, '1': '<<<sit>>>' } ] }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM