所以我有一个现有的应用程序,它在浏览器中广泛使用IIFE。我试图在代码中引入一些单元测试,并与IIFE的模式保持一致,以便对代码库进行新的更新。除此之外,我甚至无法编写一个能让我掌握代码的测试。例如,我在代码库中看到了这种类型的逻辑:
var Router = (function (router) {
router.routeUser = function(user) {
console.log("I'm in! --> " + user)
};
return router;
})(Router || {});
然后JS文件包含在标记中的脚本标记中:
<script src="js/RouteUser.js"></script>
并在生产代码中这样调用:
Router.routeUser(myUser)
所以我的问题是,如何编写测试方法 routeUser 的测试?我在我的摩卡测试中试过这个:
var router = require('../../main/resources/public/js/RouteUser');
suite('Route User Tests', function () {
test('Route The User', function () {
if (!router)
throw new Error("failed!");
else{
router.routeUser("Me")
}
});
});
但我得到一个例外:
TypeError: router.routeUser is not a function
at Context.<anonymous> (src\test\js\RouteUser.test.js:8:20)
然后我尝试返回该方法,它给出了同样的错误:
var Router = (function (router) {
return {
routeUser: function (user) {
console.log("I'm in! --> " + user)
}
}
}
)(Router || {});
有人能指出我正确的方向吗?
答案 0 :(得分:1)
听起来......
考虑到这些假设,问题是你想要你的代码......
window.Router
等)require()
UMD或通用模块定义,曾经是编写代码的常用方法,因此它可以在多个环境中工作。有趣的方法,但非常繁琐,我喜欢认为UMD现在已成为过去......
I'll leave it here for completeness.
如果您现在唯一想要制作特定脚本的东西也可以作为模块使用,那么它可以在测试中导入,您可以进行一些小调整:
var Router = (function (router) {
router.routeUser = function(user) {
console.log("I'm in! --> " + user)
};
if (typeof exports === "object") {
module.exports = router;
// now the Mocha tests can import it!
}
return router;
})(Router || {});
从长远来看,通过重写所有代码以仅使用模块并使用webpack
之类的工具为您打包,您可以获得很多好处。上述想法是朝着您的方向迈出的一小步,为您提供一个特定的好处(可测试性)。但这不是一个长期的解决方案,你在处理依赖关系时会遇到一些麻烦(如果你的路由器希望有一些全局变量,那该怎么办?)
答案 1 :(得分:1)
如果您打算在浏览器中运行Mocha测试,则无需更改现有代码。
让我们来看看IIFE模式,因为基于你的代码,我认为你可能会误解它是如何工作的。基本形状是:
var thing = (function() {
return 1;
})();
console.log(thing) // '1'
var
声明设置thing
等于等号右侧的值。在右边,第一组parens包含一个函数。然后,第二组parens就在它旁边,最后。第二组调用第一组parens中包含的函数表达式。这意味着函数的return
值将是var
语句中的右侧值。因此thing
等于1
。
在您的情况下,这意味着外部Router
变量设置为等于函数返回的router
变量。这意味着在将脚本包含在DOM中之后,您可以在测试中将其作为Router
访问:
suite('Route User Tests', function () {
test('Route The User', function () {
if (!Router) // <- Notice the capital 'R'
throw new Error("failed!");
else {
Router.routeUser("Me") // <- capital 'R'
}
});
});
如果您打算使用节点运行测试,请参阅Kos的答案。