How do I use CoffeeScript to mock out existing code?
I'd like mock out MarkdownDeep, I've the following code, in JavaScript
MarkdownDeep = new (function () {
this.Markdown = functio开发者_JAVA百科n () {
this.Transform = function (a) {
return "html";
};
};
})();
but I'm having trouble implementing this in CoffeeScript
I tried the following
MarkdownDeep = new (->
@Markdown = ->
@Transform = (a) ->
"html"
)()
window.MarkdownDeep = MarkdownDeep
but it doesn't work, specifically in my unit test markdown = new MarkdownDeep.Markdown() gives "undefined is not a function", though the JS version mocks out fine.
Your example results in the following javascript code:
var MarkdownDeep;
MarkdownDeep = new (function() {
return this.Markdown = function() {
return this.Transform = function(a) {
return "html";
};
};
});
window.MarkdownDeep = MarkdownDeep;
The line return this.Markdown = function() { /* ... */ } makes the function the object returned by the new operator.
Writing
MarkdownDeep = new (->
@Markdown = ->
@Transform = (a) ->
"html"
return
return
)
window.MarkdownDeep = MarkdownDeep
fixes the problem.
Addition: This answer mentions the algorithm for object construction in javascript
CoffeeScript's implicit returns can lead to mayhem when used in conjunction with new. As others have pointed out, you could use explicit returns. Another option is to use class, which creates a function (the constructor) with no implicit return:
MarkdownDeep = new class
constructor: ->
@Markdown = class
constructor: ->
@Transform = (a) ->
'html'
Of course, that's not very readable in this case, but as a general rule, you'll save yourself headaches by using class whenever you use new.
You need to explicitly set a return value for your objects/classes or else it will return the member functions when creating a new instance.
JS FIDDLE
MarkdownDeep = new (->
@Markdown = ->
@Transform = (a) ->
"html"
undefined #return undefined instead of this.Transform
undefined #return undefined instead of this.Markdown
)
markdown = new MarkdownDeep.Markdown()
alert markdown.Transform()
compiles to:
var MarkdownDeep, markdown;
MarkdownDeep = new (function() {
this.Markdown = function() {
this.Transform = function(a) {
return "html";
};
return;
};
return;
});
markdown = new MarkdownDeep.Markdown();
alert(markdown.Transform());
This is what Coffeescript gives as output
var MarkdownDeep;
MarkdownDeep = new (function() {
return this.Markdown = function() {
return this.Transform = function(a) {
return "html";
};
};
});
The last line in every function is implicitly returned in Coffeescript. Checking this in the console yields MarkdownDeep as
function () {
return this.Transform = function(a) {
return "html";
};
}
which returns a function that does not have Markdown() as a method.
CoffeeScript automatically wraps each output file in an anonymous function ((function() { ... })()). To disable this use the --bare or -b option when running coffee.
加载中,请稍侯......
精彩评论