I am using Coffeescript and I'm testing using Sinon.js. When testing a method that invokes the method it overwrites, how can I stub the call to super()?
E.g., the method I want to test (a backbone.js model):
class Whatever extends Model
validate: (attributes) ->
validationErrors = super(attributes)
...
validationErrors
In the example, I want to make sure that super() is invoked with the given attributes and that validate returns the validation errors super() returns.
Like this:
it 'calls super and returns its result', ->
whatever = new Whatever()
attributes = sinon.stub()
superValidateStub = sinon.mock(Whatever.__super__)
superValidateStub.expects('validate').withExactArgs(attributes).returns('VALIDATION_RESULT')
expect(whatever.validate(attributes)).to.eql('VALIDATION_RESULT')
superValidateStub.verify()
Hope this helps anyone.
Related
I load an assembly and from that a class of the object I want to create. From that class I check for interfaces (mono_class_get_interfaces) and find the interface class I want (IDispose).
I create the object with mono_object_new and call mono_runtime_object_init directly afterward. I then call mono_object_castclass_mbyref to cast the object to an interface reference. Then I retrieve the interface method I want to call (Dispose) from the interface class with mono_class_get_method_from_name.
I call mono_object_get_virtual_method to make sure I have the correct implementation and then try to call it with mono_runtime_invoke using the interface MonoObject * reference and the interface virtual method MonoMethod * (args = NULL) -> which is unsuccessful.
I have also tried to call mono_method_get_unmanaged_thunk with the same parameter, that doesn't work either.
In both cases I get a value back for the exception argument. Problem is, I haven't found a way to look inside the exception...
Question is:
Is the sequence of calls correct to work with managed interfaces and call the correct (most specific) interface methods?
How to get more information on the MonoException (I assume the MonoObject * returned by invoke is a MonoException instance)?
There is no need to invoke any castclass function to cast a managed reference to an 'interface reference': the value is the same.
Once you have your IDispose MonoClass* pointer, you should get the MonoMethod* for the method you want to call and pass that to mono_object_get_virtual_method(). The result of this function is what you should pass to mono_runtime_invoke().
For the exception, you can invoke the get_Message method method, for example, or any of the methods you'd call to deal with it if you were in C# code.
Simple tested code below, str is a MonoString*:
icloneable_class = mono_class_from_name (mono_get_corlib (), "System", "ICloneable");
iface_method = mono_class_get_method_from_name (icloneable_class, "Clone", 0);
iface_impl_method = mono_object_get_virtual_method (str, iface_method);
exc = NULL;
obj = mono_runtime_invoke (iface_impl_method, str, NULL, &exc);
The method is correctly invoked and exc will be NULL.
I have a "class" in coffee script whose instance variables I want to initialize with instance methods that return a value via a callback, but it doesn't work as I had hoped:
EventEmitter = require('events').EventEmitter
class MyClass extends EventEmitter
constructor: ->
#datamember: setDatamember()
setDatamember: ->
someFunction (response) ->
#datamember = response
#emit 'init'
getDatamember: ->
return #datamember
----
myObj = new MyClass
myObj.on 'init', ->
console.log myObj.getDatamember
The result I get suggests that "this" in setDatamember is referring to something different from what "this" refers to in the object instance. If I explicitly call myObj.setDatamember, I get the expected result, but is there any way to call on a set method -- specifically one that sets the data member via a callback -- in the constructor? I've looked through the docs, as well as various other sources of coffeescript info (e.g. this one), and I haven't found anything that touches upon this.
Try using a fat arrow for the anonymous function:
setDatamember: ->
someFunction (response) =>
#datamember = response
#emit 'init'
Also, you'll need to call the correct function in the constructor:
constructor: ->
#setDatamember()
In general, avoid fat arrows on methods - the way Coffee-Script implements this does some bad things to memory usage. Also, it will rarely be necessary.
However, anonymous functions that refer to this will almost always need fat arrows. this is not held in closure like normal variables, and will only be set by binding (Function.prototype.bind) or by calling it as an object method (obj.myMethod() will set this to obj in myMethod).
Try using fat arrows on everything except the constructor:
class MyClass
constructor: ->
#setDatamember()
setDatamember: =>
someFunction (response) =>
#datamember = response
getDatamember: =>
return #datamember
However, you also look to have someFunction in there as an asynchronous function, so you'll never be able to just do
mc = new MyClass
console.log mc.datamember
Because that doesn't wait for someFunction to return before accessing mc.datamember.
If I have a class:
class Haha
constructor: (#lolAmount = 1) ->
alert #lolAmount
And I want to check if an object is of the right class, Is it always safe to use constructor.name:
haha = new Haha()
unless haha.constructor.name is 'Haha'
throw Error 'Wrong type'
or is it better to use instanceof:
haha = new Haha()
unless haha instanceof Haha
throw Error 'Wrong type'
One argument I have for instanceof is when using extends:
class BigHaha extends Haha
bigHaha = new BigHaha
console.log bigHaha instanceof Haha #true
but how safe is it, being a JavaScript operator - I feel like I should be sceptical about it.
On the other hand, with constructor.name it is very clear what is happening. Is it guaranteed that constructor.name will be set on all objects?
Thanks for any info.
First of all, constructor is also straight JavaScript:
Returns a reference to the Object function that created the instance's prototype.
So when you say o.constructor, you're really doing straight JavaScript, the name constructor for the CoffeeScript object initialization function is a separate matter.
So now you have a choice between using JavaScript's constructor property or JavaScript's instanceof operator. The constructor just tells you what "class" was used to create the object, instanceof on the other hand:
[...] tests whether an object has in its prototype chain the prototype property of a constructor.
So instanceof is the right choice if you want to allow for subclassing.
I'm trying to subclass the native JS Error object in CoffeeScript to get specialized error types, but i found that the instanceof does not work correctly if i don't define a constructor in the subclasses:
class SimpleError extends Error
class EmptyConstructorError extends Error
constructor: ->
class SuperConstructorError extends Error
constructor: ->
super
new SimpleError instanceof SimpleError # -> false
new EmptyConstructorError instanceof EmptyConstructorError # -> true
new SuperConstructorError instanceof SuperConstructorError # -> true
The problem seems to be caused by how the generated JS constructor functions are defined. When i don't define a constructor in CoffeeScript:
SimpleError = (function(_super) {
__extends(SimpleError, _super);
function SimpleError() {
return SimpleError.__super__.constructor.apply(this, arguments);
}
return SimpleError;
})(Error);
And when i do define a constructor in CoffeeScript:
SuperConstructorError = (function(_super) {
__extends(SuperConstructorError, _super);
function SuperConstructorError() {
SuperConstructorError.__super__.constructor.apply(this, arguments);
}
return SuperConstructorError;
})(Error);
As you can see, the difference is a simple return in the first case. I don't understand why this makes any difference in the instanceof behavior though, as the super constructor is just being applied to the this object (i.e. the super constructor is not being called with new), but then again i don't understand a whole lot of how JS constructors work =P
And the weird thing is that this behavior seems to only happen when subclassing native JS objects. If i subclass CoffeeScript classes everything works as expected.
Any idea of why this might be happening and how could i avoid writing dummy constructors just for the instanceof operator to work correctly?
Thanks!
Update
So the user matyr answered with a link to the commit where this behavior was introduced, but it doesn't quite explain what is happening here, so i'll try to explain that a little bit in case anyone else wonders why this works this way.
The main problem is this inherited nasty "feature" from JavaScript which let us define a constructor function that returns an object other than the one being constructed:
function Foo() {
return {'LOL': 'You fool!'};
}
new Foo() instanceof Foo // -> false
And there is also the fact that some native constructors, like Error, Array, String and whatnot don't need to be called with new: they will just return a new object of the corresponding type if you happen to forget it.
In the end, add these two ugly things together and the result is that you should remember to write class MyError extends Error then constructor: -> super instead of the more intuitive class MyError extends Error if you want the instanceof operator to work properly with MyError. That's because CoffeeScript's implicit constructor will just return whatever the parent constructor returns, and in this case will do return Error.apply(this, arguments) which will just return a shinny new error object instead of the object you passed as the this argument. Yay!
Update 2 (Feb 25 2013)
This problem was fixed in CoffeeScript 1.5.0! =D
Now extending native objects works as expected:
class MyError extends Error
new MyError instanceof MyError # -> true :)
Update 3 (Mar 04 2013)
Aaand it's gone on 1.6.0 =P
For better or worse, the return was added on 1.3.1 to fix #1966 (and #2111).
I am re-writing this question to make it clearer what I need to do. I am trying to use Rhino-Mock to test:
public IQueryable<TxRxMode> GetAllModes()
{
return m_context.TxRxModes.Where(txRxMode => txRxMode.Active);
}
Here's the code:
var context = MockRepository.GenerateStub<IProjectContext>();
//Returns an empty list
context.Expect(c => c.TxRxModes.Where(Arg<Func<TxRxMode, bool>>.Is.Anything)).Return(new List<TxRxMode>().AsQueryable());
TxRxModes in an IObjectSet property on the context and I want it to return an empty IQueryable<TxRxMode> object when the return m_context.TxRxModes.Where(txRxMode => txRxMode.Active); code is called.
When I run this, the Expect method call throws the an ArgumentNullException:
Value cannot be null.
Parameter name: predicate
I have tried the simpler:
IObjectSet<TxRxMode> modes = MockRepository.GenerateStub<IObjectSet<TxRxMode>>();
context.Expect(c => c.TxRxModes).Return(modes);
but this throws a null reference exception when I call
return m_context.TxRxModes.Where(txRxMode => txRxMode.Active);
Basically, this is part of the method I am trying to mock, so the key question is how do I mock this Where statement?
Where is actually a global static method and you shouldn't be mocking it. It operates on an IEnumerable however and you could just mock that.
Its kind of a hassle doing it with rhino mocks however. I would recommend doing the mock manually (if you need to do it at all).