Search code examples
javascriptnode.jsmocha.jsnode-assert

Prototype function overriden by other "class"


I have the following inputModel:

var UserCreateInputModel = function(req) {
    ...
    this.password = req.body.password;
    this.repeatPassword = req.body.repeatPassword;
    ...

    console.log(this.password !== this.repeatPassword);

    this.validate();
};
UserCreateInputModel.prototype = InputModel;

UserCreateInputModel.prototype.validate = function() {
    console.log('Validating...');
    if(this.password !== this.repeatPassword) throw new Error('Passwords are not equal!');
};

module.exports = UserCreateInputModel;

In my test I would like to test if the exception was thrown (using node's assert module):

//Act
assert.throws(function() {
    new UserCreateInputModel(req);
}, Error);

Somehow the exception is just not thrown. My console output from the constructor is "this". On the console I don't see the output "Validating".

I guess this is some JavaScript pitfall or something like that (about this) but I'm just not getting the error ...

Update I have another inputModel in another file. This "inherites" from InputModel too. So it seems UserCreateInputModel.prototype.validate is overridden in the other inputModel. Still don't get it ...


Solution

  • This line:

    UserCreateInputModel.prototype.validate = function() {
        console.log('Validating...');
        if(this.password !== this.repeatPassword) throw new Error('Passwords are not equal!');
    };
    

    is modifying the InputModel object. If you have two different types "inheriting" from InputModel with what you have here, and they both have validate methods, then one is overwriting the other.

    To properly inherit from InputModel, use Object.create():

    UserCreateInputModel.prototype = Object.create(InputModel.prototype);
    

    And then call the parent constructor from your child constructor:

    var UserCreateInputModel = function(req) {
        InputModel.call(this, <arguments>);
    

    This way, when you modify UserCreateInputModel.prototype, you will only be modifying UserCreateInputModel.prototype and not anything else.