Javascript 如何测试被测试函数中未返回的被调用承诺

Javascript 如何测试被测试函数中未返回的被调用承诺,javascript,node.js,testing,promise,mocha.js,Javascript,Node.js,Testing,Promise,Mocha.js,首先,我已经尝试了几乎所有的方法来让这段代码工作,我实现了,问题是我不喜欢这种方法,我想知道是否有更好的方法可以让测试代码更可读,但更实用 我想断言(例如,sinon)第二个函数(secondApiCall)已被调用,但似乎无法实现,您将如何实现它。是否有一种非黑客方法 这里的主要问题是“我不能修改functionToTest”,我必须编写基本上检查API调用是否完成的测试 在functionToTest完成后,如何使用给定的代码运行断言 PS:代码很糟糕,我知道,但有时你不得不处理它,你不能做

首先,我已经尝试了几乎所有的方法来让这段代码工作,我实现了,问题是我不喜欢这种方法,我想知道是否有更好的方法可以让测试代码更可读,但更实用

我想断言(例如,
sinon
第二个函数(
secondApiCall
)已被调用,但似乎无法实现,您将如何实现它。是否有一种非黑客方法

这里的主要问题是“我不能修改
functionToTest
”,我必须编写基本上检查API调用是否完成的测试

functionToTest
完成后,如何使用给定的代码运行断言

PS:代码很糟糕,我知道,但有时你不得不处理它,你不能做更多的事情,只需在重构之前测试它:(

基本上,生成mock的代码是这样做的,所以在最后您有了同步代码

const firstApiCall = () => {
    return {
        then: (cb) => {
            cb('firstApiCall success')
        }
    }
};

非常感谢!

除非承诺被返回,否则无法检查第二个API调用是否直接发生

const firstApiCall = () => {
    return {
        then: (callback) => {
            callback('firstApiCall success');
        }
    }
};
如下所述:

const functionToTest = () => {
  setTimeout(() => {
    firstApiCall().then(result => {
      setTimeout(() => {
        secondApiCall()
      }, 2)
    })
  }, 15)
};
承诺没有兑现,所以你对此无能为力

我想说,在这里模拟函数是没有用的

如果不能直接测试,可以尝试间接测试:即使非常糟糕,也可以通过函数调用的API检查API后面的资源状态在第二次调用后是否已按预期更改。
如果您不能很好地通过API进行测试……那么就没有什么可测试的了。

除非承诺被返回,否则您无法检查第二个API调用是否直接发生

const firstApiCall = () => {
    return {
        then: (callback) => {
            callback('firstApiCall success');
        }
    }
};
如下所述:

const functionToTest = () => {
  setTimeout(() => {
    firstApiCall().then(result => {
      setTimeout(() => {
        secondApiCall()
      }, 2)
    })
  }, 15)
};
承诺没有兑现,所以你对此无能为力

我想说,在这里模拟函数是没有用的

如果不能直接测试,可以尝试间接测试:即使非常糟糕,也可以通过函数调用的API检查API后面的资源状态在第二次调用后是否已按预期更改。
如果你不能很好地通过API进行测试……那么就没有什么可测试的了。

在尝试了几件事情之后,你总是可以做的,就是模拟第一个API调用,因此在最后,你将有一个sync调用,而不是async调用,这要感谢回调,我将在这里留下一个例子,供测试时需要灵感的人参考不兑现的承诺

const firstApiCall = () => {
    return {
        then: (callback) => {
            callback('firstApiCall success');
        }
    }
};

PS:再一次,这个解决方案不是最漂亮的,但它至少可以工作。

在尝试了几件事情之后,你总是可以做的,就是模拟第一个API调用,因此在最后,你将有一个sync调用,而不是async调用,这要感谢回调,我将在这里留下一个例子,给需要灵感的人不退还的承诺

const firstApiCall = () => {
    return {
        then: (callback) => {
            callback('firstApiCall success');
        }
    }
};

PS:同样,这个解决方案不是最漂亮的,但它至少可以工作。

在functionToTest完成后,如何使用给定的代码运行断言?
-您不能这样做,因为
functionToTest
既不返回任何内容,也不在完成时回调任何内容……这是一个写得很差的异步测试function@JArmondax我完全同意你的看法,我处理的ATM代码不是很好,但不知怎么的,必须有人维护它:(问题是,“除非你能验证没有行为改变,否则你不能改变某些东西”,而这只能通过测试来完成(即使测试很难看,几乎不可能)如果不更改代码,您就无法测试它。您说您不能,所以不要测试它。这不是一个好答案,但却是唯一合法的答案。如果api调用影响有状态更改,您可以轮询更改是否已在承诺循环中生效,如果超过n毫秒,则测试失败。这也不太好,但您会被卡住。
如何处理t给定的代码在functionToTest完成后您会运行断言吗?
-您不能,因为
functionToTest
既不返回任何内容,也不在完成时回调任何内容……这是一个写得很糟糕的异步测试function@JaromandaX我完全同意你的看法,我处理的不是很好的ATM代码,但不知怎么的必须有人维护它:(问题是,“除非你能证实没有行为改变,否则你不能改变某些东西”,这只能通过测试来完成(即使测试很难看,几乎不可能)如果不更改代码,您就无法测试它。您说您不能,所以不要测试它。这不是一个好答案,但却是唯一合法的答案。如果api调用影响有状态更改,您可以轮询更改是否已在承诺循环中生效,如果超过n毫秒,则测试失败。这也不太好,但您会陷入困境。