让requirejs与Jasmine一起工作

The*_*eek 66 javascript bdd unit-testing requirejs jasmine

我首先想说的是我是RequireJS的新手,甚至是Jasmine的新手.

我有一些SpecRunner的问题,需要JS.我一直在关注Uzi Kilon和Ben Nadel(以及其他一些人)的教程,他们帮助了一些,但我仍然遇到了一些问题.

看来,如果在测试中抛出错误(我可以想到一个特别是类型错误),将显示spec runner html.这告诉我,我在javascript中有一些问题.但是,在我修复这些错误后,不再显示HTML. 我根本无法让测试跑者显示出来.有人发现我的代码可能会导致此问题吗?

这是我的目录结构:

Root 
|-> lib
    |-> jasmine
        |-> lib (contains all of the jasmine lib)
        |-> spec
        |-> src
    |-> jquery (jquery js file)
    |-> require (require js file) 
index.html (spec runner) specRunner.js
Run Code Online (Sandbox Code Playgroud)

这是SpecRunner(索引)HTML:

<!doctype html>
<html lang="en">
    <head>
        <title>Javascript Tests</title>

        <link rel="stylesheet" href="lib/jasmine/lib/jasmine.css">

        <script src="lib/jasmine/lib/jasmine.js"></script>
        <script src="lib/jasmine/lib/jasmine-html.js"></script>
        <script src="lib/jquery/jquery.js"></script>
        <script data-main="specRunner" src="lib/require/require.js"></script>

        <script>
            require({ paths: { spec: "lib/jasmine/spec" } }, [
                    // Pull in all your modules containing unit tests here.
                    "spec/notepadSpec"
                ], function () {
                    jasmine.getEnv().addReporter(new jasmine.HtmlReporter());
                    jasmine.getEnv().execute();
                });
        </script>

    </head>

<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

这是specRunner.js(config)

require.config({
    urlArgs: 'cb=' + Math.random(),
    paths: {
        jquery: 'lib/jquery',
        jasmine: 'lib/jasmine/lib/jasmine',
        'jasmine-html': 'lib/jasmine/lib/jasmine-html',
        spec: 'lib/jasmine/spec/'
    },
    shim: {
        jasmine: {
            exports: 'jasmine'
        },
        'jasmine-html': {
            deps: ['jasmine'],
            exports: 'jasmine'
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这是一个规范:

require(["../lib/jasmine/src/notepad"], function (notepad) {
    describe("returns titles", function() {
        expect(notepad.noteTitles()).toEqual("");


    });
});
Run Code Online (Sandbox Code Playgroud)

记事本来源:

define(['lib/jasmine/src/note'], function (note) {

    var notes = [
        new note('pick up the kids', 'dont forget to pick  up the kids'),
        new note('get milk', 'we need two gallons of milk')
    ];


    return {
        noteTitles: function () {
            var val;

            for (var i = 0, ii = notes.length; i < ii; i++) {
                //alert(notes[i].title);
                val += notes[i].title + ' ';
            }

            return val;
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

而Note源(JIC):

define(function (){
    var note = function(title, content) {
        this.title = title;
        this.content = content;
    };

    return note;
});
Run Code Online (Sandbox Code Playgroud)

我已经确定,就应用程序而言,路径是正确的.一旦我开始工作,我就可以配置这些路径,这样它就不那么令人讨厌了.

The*_*eek 57

我设法通过一些试验和错误来解决这个问题.主要问题是当你编写规范时,它不是你想要创建的要求,你想使用define:

原版的:

require(["/lib/jasmine/src/notepad"], function (notepad) {
    describe("returns titles", function() {
        expect(notepad.noteTitles()).toEqual("pick up the kids get milk");


    });
});
Run Code Online (Sandbox Code Playgroud)

工作:

define(["lib/jasmine/src/notepad"], function (notepad) {
    describe("returns titles", function () {

        it("something", function() {

            expect(notepad.noteTitles()).toEqual("pick up the kids get milk ");
        });

    });
});
Run Code Online (Sandbox Code Playgroud)

经过一些研究后,很明显,当使用RequireJS时,任何你想要require()的东西都必须包含在一个定义中(现在我觉得很明显).您可以看到,在specRunner.js文件中,在执行测试时使用了需求(因此需要"定义"规范.

另一个问题是,在创建规范时,describe()和it()是必要的(不仅仅是我在发布的示例中所描述的描述).

原版的:

describe("returns titles", function() {
        expect(notepad.noteTitles()).toEqual("pick up the kids get milk");


    });
Run Code Online (Sandbox Code Playgroud)

工作:

describe("returns titles", function () {

        it("something", function() {

            expect(notepad.noteTitles()).toEqual("pick up the kids get milk ");
        });

    });
Run Code Online (Sandbox Code Playgroud)

我也改变了测试运行器存在的位置,但这是一个重构,并没有改变测试的结果.

同样,这里是文件和更改:

note.js:保持不变

notepad.js:保持不变

index.html的:

<!doctype html>
<html lang="en">
    <head>
        <title>Javascript Tests</title>
        <link rel="stylesheet" href="lib/jasmine/lib/jasmine.css">
        <script data-main="specRunner" src="lib/require/require.js"></script>
    </head>

    <body>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

specRunner.js:

require.config({
    urlArgs: 'cb=' + Math.random(),
    paths: {
        jquery: 'lib/jquery',
        'jasmine': 'lib/jasmine/lib/jasmine',
        'jasmine-html': 'lib/jasmine/lib/jasmine-html',
        spec: 'lib/jasmine/spec/'
    },
    shim: {
        jasmine: {
            exports: 'jasmine'
        },
        'jasmine-html': {
            deps: ['jasmine'],
            exports: 'jasmine'
        }
    }
});


require(['jquery', 'jasmine-html'], function ($, jasmine) {

    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;

    var htmlReporter = new jasmine.HtmlReporter();

    jasmineEnv.addReporter(htmlReporter);

    jasmineEnv.specFilter = function (spec) {
        return htmlReporter.specFilter(spec);
    };

    var specs = [];

    specs.push('lib/jasmine/spec/notepadSpec');



    $(function () {
        require(specs, function (spec) {
            jasmineEnv.execute();
        });
    });

});
Run Code Online (Sandbox Code Playgroud)

notepadSpec.js:

define(["lib/jasmine/src/notepad"], function (notepad) {
    describe("returns titles", function () {

        it("something", function() {

            expect(notepad.noteTitles()).toEqual("pick up the kids get milk");
        });

    });
});
Run Code Online (Sandbox Code Playgroud)


Goh*_*n67 12

只需将此添加为您使用Jasmine 2.0独立版的人的替代答案.我相信这也适用于Jasmine 1.3,但异步语法不同而且有点难看.

这是我修改过的SpecRunner.html文件:

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Jasmine Spec Runner v2.0.0</title>

  <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
  <link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">

  <!-- 
  Notice that I just load Jasmine normally
  -->    
  <script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
  <script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
  <script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>

  <!-- 
  Here we load require.js but we do not use data-main. Instead we will load the
  the specs separately. In short we need to load the spec files synchronously for this
  to work.
  -->
  <script type="text/javascript" src="js/vendor/require.min.js"></script>

  <!-- 
  I put my require js config inline for simplicity
  -->
  <script type="text/javascript">
    require.config({
      baseUrl: 'js',
      shim: {
          'underscore': {
              exports: '_'
          },
          'react': {
              exports: 'React'
          }
      },
      paths: {
          jquery: 'vendor/jquery.min',
          underscore: 'vendor/underscore.min',
          react: 'vendor/react.min'
      }
    });
  </script>

  <!-- 
  I put my spec files here
  -->
  <script type="text/javascript" src="spec/a-spec.js"></script>
  <script type="text/javascript" src="spec/some-other-spec.js"></script>
</head>

<body>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

现在这是一个示例spec文件:

describe("Circular List Operation", function() {

    // The CircularList object needs to be loaded by RequireJs
    // before we can use it.
    var CircularList;

    // require.js loads scripts asynchronously, so we can use
    // Jasmine 2.0's async support. Basically it entails calling
    // the done function once require js finishes loading our asset.
    //
    // Here I put the require in the beforeEach function to make sure the
    // Circular list object is loaded each time.
    beforeEach(function(done) {
        require(['lib/util'], function(util) {
            CircularList = util.CircularList;
            done();
        });
    });

    it("should know if list is empty", function() {
        var list = new CircularList();
        expect(list.isEmpty()).toBe(true);
    });

    // We can also use the async feature on the it function
    // to require assets for a specific test.
    it("should know if list is not empty", function(done) {
        require(['lib/entity'], function(entity) {
            var list = new CircularList([new entity.Cat()]);
            expect(list.isEmpty()).toBe(false);
            done();
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

以下是来自Jasmine 2.0文档的异步支持部分的链接:http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support