Javascript 如何在浏览器中模拟文件选择器进行单元测试?

Javascript 如何在浏览器中模拟文件选择器进行单元测试?,javascript,firefox,browser,jasmine,Javascript,Firefox,Browser,Jasmine,我对如何在浏览器中全局模拟文件选择器感兴趣。具体来说,我最感兴趣的是在Firefox中实现这一点,但我更喜欢一个通用的解决方案 我只关心防止出现文件选择器对话框。我不需要断言它确实打开了。问题是我对打开文件选择器的JavaScript代码进行了单元测试。当对话框打开时,它将停止测试套件的执行 例如,我正在测试主干.View的onRender方法。该方法渲染子视图,渲染时将打开文件选择器。由于我没有直接测试该子视图,所以当我只对onRender方法的其他部分进行单元测试时,我不希望模拟它的部分行为

我对如何在浏览器中全局模拟文件选择器感兴趣。具体来说,我最感兴趣的是在Firefox中实现这一点,但我更喜欢一个通用的解决方案

我只关心防止出现文件选择器对话框。我不需要断言它确实打开了。问题是我对打开文件选择器的JavaScript代码进行了单元测试。当对话框打开时,它将停止测试套件的执行

例如,我正在测试
主干.View
onRender
方法。该方法渲染子视图,渲染时将打开文件选择器。由于我没有直接测试该子视图,所以当我只对
onRender
方法的其他部分进行单元测试时,我不希望模拟它的部分行为

例如:

//Test file
it("should do something", function() {
  var view = new App.Views.SomeView();
  spyOn(view.modelBinder, "bind");
  view.render();
  expect(view.modelBinder.bind).toHaveBeenCalled();
});

//View file
onRender : function () {
  this.modelBinder.bind(this.el, this.model);
  this.$("#thing").html(this.subview.render().el); //This line has a side effect that opens file picker
}
本质上,我不想显式模拟导致文件选择器被打开的行为,因为我不想在这里测试它。这样做会使测试套件更脆弱,更难维护。

用于模拟/监视/清除调用。您可以测试正在进行的调用,而不是实际进行调用


这样,您就可以测试函数是否已被调用,而无需调用显示对话框的实际函数。

要回答您的问题:不要这样做。

我将用一个空函数替换
subview.render()
,以避免不必要的副作用。但是你说:

“我不想明确地嘲弄导致错误的行为 要打开的文件选取器,因为它不是我感兴趣的测试内容

这有点矛盾。如果你想对App.Views.SomeView进行单元测试,你必须模仿外部的合作者,特别是在不感兴趣的时候,包括你的文件选择器。另一方面,您不应该在单元测试时弄乱它

模拟实际上会使您的测试更容易出现红色,但这是确保您的生产代码不会遭受不良耦合形式(IMHO,Backbone.js应用程序的常见陷阱)的唯一方法


唯一需要避免显示文件选择器的地方是在单元测试文件选择器本身时,在这种情况下,您可以按建议使用sinon,或者如果使用jQuery,则不覆盖它。记住“永远不要模仿你不拥有的类型”规则。

使用的是js测试驱动程序吗?帮我一个忙,添加单元测试,并在显示它的函数被调用的地方添加注释。添加了一些代码并解释了这种情况。要回答你的第一个问题,没有。我使用Jasmine作为我的测试框架。这有帮助吗(在此页面中对文件选择器进行文本搜索)?我不希望这样做,因为在整个套件中,导致文件选取器打开的原因各不相同。我希望能够全局阻止选取器打开。在上面添加了一些解释,说明为什么我不希望删除导致文件选取器打开的特定方法/事件。@andrewhubs如果您的单元测试是依赖于API而不是您正在编写的API,您做的单元测试是错误的,然后它变成了集成测试而不是单元测试。单元测试的确切含义是…测试软件中的单个功能单元,以您期望的方式工作。也就是说,我对jasmine一无所知。jsle感谢您的支持cture介绍了单元测试的原理。它既提供了信息又很有用。