在 javascript 认为文档“准备好"之前,如何让我的 jasmine 测试装置加载?

2022-01-11 00:00:00 tdd ruby-on-rails jasmine jquery javascript

我相当确定问题在于设置为在 $(document).ready 上运行的 jquery 绑定没有可用的夹具 html.因此,当我的事件发生旨在通过 jquery 函数对 DOM 进行更改时,什么也没有发生,我的测试也失败了.我在这里看到了这个问题的解决方案",但是那个解决方案这对我有用,需要更改我的工作 jquery 函数以绑定 .live 方法而不是 .click 方法.我对此有两个问题.首先,我不想更改我的工作代码,以便测试能够正确通过.测试框架应该测试代码是否可以在应用程序中工作,其中 DOM 加载和 javascript 绑定以正确的顺序发生.我对解决方案的第二个问题是 .on 和 .delegate 由于某种原因都不起作用,唯一最终起作用的是使用 .live 方法,该方法目前正在被弃用.总之,我想弄清楚如何更改我的测试或测试框架本身,以便在 $(document).ready 中运行的函数之前加载固定装置.

I am fairly certain that the issue is that the jquery bindings set to run on $(document).ready do not have the fixture html available to them. So when my events occur that are intended to make a change to the DOM via a jquery function, nothing happens, and my tests fail. I saw a "solution" to this problem here, but that solution which did work for me, required changing my working jquery function to bind with the .live method instead of the .click method. I have two issue with this. First I do not want to have to change my working code so that the tests will pass properly. The testing framework ought to test whether the code will work in the app, where the DOM load and the javascript bindings occur in the correct order. The second issue I have with the solution is that .on and .delegate both did not work for some reason and the only thing that ended up working was to use the .live method which is currently in the process of being deprecated. In conclusion, I would like to figure out how to change either my tests or the testing framework itself, such that the fixtures are loaded before the functions that run in $(document).ready.

我正在使用 rails 3.2.8,并且设置了两个不同的分支来进行 jasmine 测试.其中一个分支使用 jasminerice gem,另一个使用 jasmine-rails gem.Javascript 和 jQuery(使用 .live 方法时)测试都在这两种设置中正确通过.

I am working with rails 3.2.8 and I have two different branches set up to experiment with jasmine testing. One of the branches uses the jasminerice gem and the other uses the jasmine-rails gem. The Javascript and jQuery(when using the .live method) tests all pass properly in both of these set-ups.

这里是使用茉莉花的分支的描述:

Here is a description of the branch using jasminerice:

以下是我的 Gemfile.lock 文件中描述 jasmine 和 jQuery 设置的行:

Here are the lines from my Gemfile.lock file describing the jasmine and jQuery set-up:

jasminerice (0.0.9)
  coffee-rails
  haml
jquery-rails (2.1.3)
  railties (>= 3.1.0, < 5.0)
  thor (~> 0.14)

Jasminerice 默认包含 jasmine-jquery 扩展.jasmine-jQuery 扩展提供了我在测试中使用的 toHaveText 方法.

Jasminerice includes the jasmine-jquery extension by default. The jasmine-jQuery extension provides the toHaveText method I am using in the tests.

直接位于 spec/javascripts 目录中的测试文件 jasmine_jquery_test.js 包含以下内容:

The test file jasmine_jquery_test.js which is located directly within the spec/javascripts directory contains this content:

#= require application

describe ("my basic jasmine jquery test", function(){

    beforeEach(function(){
        $('<a id="test_link" href="somewhere.html">My test link</a>').appendTo('body');
    });

    afterEach(function(){
        $('a#test_link').remove();
    });

    it ("does some basic jQuery thing", function () {
        $('a#test_link').click();
        expect($("a#test_link")).toHaveText('My test link is now longer');
    });

    it ("does some the same basic jQuery thing with a different trigger type", function () {
        $('a#test_link').trigger('click');
        expect($("a#test_link")).toHaveText('My test link is now longer');
    });

});
describe ('subtraction', function(){

    var a = 1;
    var b = 2;

    it("returns the correct answer", function(){
        expect(subtraction(a,b)).toBe(-1);
    });

});

我位于 app/assets/javascripts 目录中的 javascript 文件 tests.js 包含以下内容:

My javascript file tests.js which is located in the app/assets/javascripts dir has this content:

function subtraction(a,b){
    return a - b;
}

jQuery (function($) {
/* 
    The function I would rather use - 
    $("a#test_link").click(changeTheTextOfTheLink)
    function changeTheTextOfTheLink(e) {
        e.preventDefault()
        $("a#test_link").append(' is now longer');
    }
*/

    $("a#test_link").live('click', function(e) {
        e.preventDefault();
        $("a#test_link").append(' is now longer');
    });

});

我位于同一 app/assets/javascripts 目录中的 application.js 文件包含以下内容:

My application.js file located in the same app/assets/javascripts dir has this content:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require vendor
//= require_tree . 

并且jasmine-rails分支的描述可以在我的第一个 jasmine 测试相关的 stackoverflow 问题.

And the description of the jasmine-rails branch can be found in the content of my first jasmine test related stackoverflow question.

如果有人知道如何操作测试,以便在加载固定装置后运行 $(document).ready 函数,我非常想听听您的想法?

So if anyone has an idea how to manipulate the tests such that the $(document).ready functions are run after the fixtures are loaded I would very much like to hear your thoughts?

推荐答案

将 jQuery 直接添加到 html 夹具对我来说可以获得所需的行为.这并不完全是这个问题的答案,但我开始相信它是目前可用的最佳解决方案.我在 jasmine-rails gem 设置中所做的更改,我还没有在 jasminerice 分支中尝试过.

Adding the jQuery directly to the html fixture worked for me to get the desired behavior. It is not exactly an answer to this question, but I am starting to believe it's the best solution currently available. My changes where made in the jasmine-rails gem set-up and I haven't yet tried it in the jasminerice branch.

这是我的测试文件:

describe ("my basic jasmine jquery test", function(){

    beforeEach(function(){
        loadFixtures('myfixture.html');
    });

    it ("does some basic jQuery thing", function () {
        $('a#test_link').click();
        expect($("a#test_link")).toHaveText('My test link is now longer');
    });

    it ("does the same basic jQuery thing with a different event initiation method", function () {
        $('a#test_link').trigger('click');
        expect($("a#test_link")).toHaveText('My test link is now longer');
    });

});
describe ('substraction', function(){

    var a = 1;
    var b = 2;

    it("returns the correct answer", function(){
        expect(substraction(a,b)).toBe(-1);
    });

});

这是我的夹具文件:

<a id="test_link" href="somewhere.html">My test link</a>

<script>
    $("a#test_link").click(changeTheTextOfTheLink)
    function changeTheTextOfTheLink(e) {
        e.preventDefault()
        $("a#test_link").append(' is now longer');
    }
</script>

相关文章