如何在jquery插件中对私有方法进行unit testing?

也许这是一个新手JQuery问题但是:

  • 正确的jquery插件写在一个闭包内
  • 因此,只有定义插件接口的方法才能从外部访问
  • 有时(或多次)可能需要帮助方法,因为它们作为插件接口的一部分公开是没有意义的(例如因为它们改变了内部状态)。
  • 那些如何进行unit testing?

例如,看看blockUI插件,方法如何安装,删除,重置获得unit testing?

要在Java中绘制并行,我会:

  1. 创建一个仅包含公共方法的BlockUI接口(根据定义)
  2. 创建一个实现上述接口的BlockUIImpl类。 此类将包含install(),remove(),reset()方法,这些方法可以是公共的,或(包)受保护的

所以,我会对Impl进行unit testing,但客户端程序员会通过BlockUI接口与插件进行交互。

这同样适用于任何其他语言和测试私有:要测试私有方法,您应该通过公共接口来练习它们。 换句话说,通过调用公共方法,私有方法在进程中进行测试,因为公共方法依赖于私有方法。

通常,私有方法不会与公共接口分开测试 – 整个问题是它们是实现细节,测试通常不应该对实现的细节有太多了解。

在JavaScript中的函数内部编写的代码,或者在调用它时的闭包 ,不一定与该函数的外部隔离。

知道函数可以看到定义它们的范围是很有用的。 您创建的任何闭包都包含包含它的代码的范围,因此也包含函数。

这个带有jQuery插件和人工“命名空间”的简单示例可能有助于certificate这一假设:

// Initialise this only when running tests my_public_test_namespace = function(){}; jQuery.fn.makeItBlue = function() { makeItBlue(this); function makeItBlue(object) { object.css('color','blue'); } if(typeof my_public_test_namespace != "undefined") { my_public_test_namespace.testHarness = function() { return { _makeItBluePrivateFn: makeItBlue } }; } }; $("#myElement").makeItBlue(); // make something blue, initialise plugin console.debug(my_public_test_namespace.testHarness()._makeItBluePrivateFn); 

但不要忘记你不应该真的测试私人。 ;)

我想出了同样的问题,在浏览并找到不真正适用的答案之后,我最终解决了类似的问题。

问题:“我有一个小部件,它有一个我想测试的行为,以确保它按预期工作,一些方法在内部调用,因为他们必须解决内部行为,公开它们没有意义因为它们不会被调用从外面来看,测试公共方法意味着你不会测试小部件的内部,所以最后我该怎么办?“

解决方案:“Creata是一个测试小部件,它公开了你有兴趣测试的方法并在qunit中使用它们,这里是一个例子:”

 // Namespaces to avoid having conflicts with other things defined similarly var formeditortest = formeditortest || {}; // widget that inherits from the container I want to test $.widget( "app.testcontainer", $.app.container, { executeDrop: function(drop, helper) { var self = this; self._executeDrop(drop, helper); } }); // Test cases formeditortest.testDropSimple = function(assert) { var container = $("
"); container.testcontainer(); container.testcontainer("drop", 0, 3); assert.equal(true, $(innerDiv.children()[0]).hasClass("droparea")); }); QUnit.test(name, function( assert ) { formeditortest.testDropSimple(assert); formeditortest.testDropBottom(assert); });

使用这种方法,inheritance的测试容器可以进行测试元素所需的准备,然后qunit将处理测试,这解决了我的问题,希望这适用于有麻烦接触这类测试的其他人。

批评? 欢迎发表评论,如果我做傻事,我想改进这个!