Тестирование Coffeescript с Жасмином и Rails 3.1 - PullRequest
5 голосов
/ 03 ноября 2011

Скажем, у меня есть класс в Coffeescript:

class MyGame
   constructor: () ->
      @me = new Player
      @opponents = [new Player, new Player]

, который я хотел бы проверить в Жасмин:

describe "MyGame", ->
   beforeEach ->
     window.game = new MyGame

   it "should have two players", ->
      expect(window.game.opponents.length).toEqual 2

Но я получаю ошибку TypeError: Result of expression 'window.game.opponents' [undefined] is not an object.?

Подход window.game также кажется мне неловким.Если я попытаюсь определить его как @game = new MyGame, я получу ошибку ReferenceError: Can't find variable: MyGame, но я думаю, что это как-то связано с тем, как Coffeescript завершает работу?

ОБНОВЛЕНИЕ: Проблемабольше похоже на проблему со ссылкой, как описано вышеЯ использую guard-jasmine, который выглядит как

guard 'jasmine', :all_on_start => false, :all_after_pass => false do
  watch(%r{app/assets/javascripts/(.+)\.(js\.coffee|js)}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
  watch(%r{spec/javascripts/(.+)_spec\.(js\.coffee|js)})  { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
  watch(%r{spec/javascripts/spec\.(js\.coffee|js)})       { "spec/javascripts" }
end

, а мой jasmine.yml файл имеет:

src_files:
    - "app/assets/**/*.js"
    - "app/assets/**/*.coffee"
spec_files: 
    - '**/*[sS]pec.js.coffee' 
asset_pipeline_paths: 
    - app/assets 
    - spec/javascripts

Я получаю ReferenceError: Can't find variable: MyGame, так что я думаю, что это либо что-тос конвейером ресурсов Rails 3.1 или способом, которым Coffeescript оборачивает объекты.

Ответы [ 4 ]

8 голосов
/ 10 февраля 2012

попробуйте определить свой класс coffeescript с помощью оператора @ следующим образом:

class @MyGame
   constructor: () ->
      @me = new Player
      @opponents = [new Player, new Player]

это позволит вам получить доступ к классу из любого места, например, из тестов с жасмином, а также вы можете уйтиот присоединения проверочных переменных к окну:

describe "MyGame", ->
   beforeEach ->
     @game = new MyGame

   it "should have two players", ->
      expect(@game.opponents.length).toEqual 2

причина этого в том, что coffeescript старается изо всех сил избегать введения глобальных переменных, оборачивая все в замыкание.к сожалению, это может быть нежелательно для объектно-ориентированного кода.использование оператора @ присоединяет определение класса к глобальному this, то есть к окну, и, таким образом, позволяет создавать экземпляры ваших классов так, как вам нравится.у вас могут быть некоторые глобальные переменные в вашем глобальном пространстве сейчас, ваши классы, но для меня это хороший компромисс.надеюсь, это поможет!

4 голосов
/ 24 июня 2012

Я не хотел соглашаться на изменение пространства имен моего кода, используя символ @ перед всеми моими базовыми классами, поэтому я покопался еще немного, и решение, которое работало для меня, заключалось в том, чтобы запросить файл приложения в моемфайл spec / javascripts / spec.js.coffee

#= require application
1 голос
/ 03 ноября 2011
window.game = () -> new MyGame

Это назначит функцию, которая возвращает новую MyGame для window.game. Вы не просто хотели новый экземпляр напрямую?

window.game = new MyGame

Подход window.game также кажется мне неловким.

Как насчет этого

describe "MyGame", ->
   game = null

   beforeEach ->
     game = new MyGame

   it "should have two players", ->
      expect(game.opponents.length).toEqual 2
0 голосов
/ 03 ноября 2011

Я решил проблему, определив каждый класс как class window.MyGame, например. В спецификациях я поставил #= require my_file_name в верх.

Кроме того, я поместил и jasminerice.js.coffee, и jquery.js в app/assets/javascripts. Возможно, это не лучшее решение, так как я предполагаю, что они должны быть помещены в spec/javascripts/helpers, поскольку мой контент spec.js.coffee равен #=require_tree ./.

Я знаю, что это не очень элегантно, но может помочь другим в такой же ситуации. @ Thilo спасибо за ваш вклад.

...