简体   繁体   中英

How to make this test pass in Mocha?

I'm using angular, chai, angularmocks, mocha, karma. The test output this error:

Type error

map@[native code]

app/main.coffee:30:23 <- app/main.js:23:23

test/main.spec.coffee:59:20 <- test/main.spec.js:18:27

assert = chai.assert
expect = chai.expect

describe("The Address Book App", () ->
  describe("the proper filter", () ->
    proper = null
    beforeEach( () ->
      module("AddressBook")
      inject( ($injector)->
        proper = $injector.get("$filter")("proper")
      )
    )

    it("should proper case a string", () ->
      expect(proper("ned stark")).to.equal("Ned Stark")
    )
  )
)

main.coffee

class AddressBook
  constructor: ->
    return []

class Proper
  uppercase: (word) ->
    word[0].toUpperCase().concat(word.slice(1))

  constructor: () ->
    return (name) ->
      words = name.toString().split(" ")
      return words.map(@uppercase).join(" ")


angular.module('AddressBook', new AddressBook())
.filter('proper', [Proper])

Updated

I think a class method 'uppercase' is more appropriate for this case and with a little change in 'main.coffee' the test pass.

class AddressBook
  constructor: ->
    return []

class Proper
  @uppercase: (word) ->
    word[0].toUpperCase().concat(word.slice(1))

  constructor: () ->
    return (name) ->
      words = name.toString().split(" ")
      return words.map(Proper.uppercase).join(" ")


angular.module('AddressBook', new AddressBook())
.filter('proper', [Proper])

But if i really need and instance method, how to make the test pass?

It's because of the way CoffeeScript handles the this keyword. In your constructor, you are returning a function, but inside that function the variable @uppercase is accessed. In this case, you want the this keyword (ie the @ ) to reference the object instance that is being constructed. However, this always references the object on which the function is called, which is this case is undefined .

To fix it, simply use the fat arrow, and CoffeeScript will set the this keyword as expected:

class Proper
  uppercase: (word) ->
    word[0].toUpperCase().concat(word.slice(1))

  constructor: () ->
    return (name) =>
      words = name.toString().split(" ")
      return words.map(@uppercase).join(" ")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM