简体   繁体   中英

Mocha returns undefined for prototype method

I'm trying to run some Mocha tests against a Node module that uses the prototype pattern for creating objects. The code itself runs just fine, but the tests don't.

Here's the code I'm trying to test:

"use strict";

const fs = require("fs"),
  request = require("request"),
  EventEmitter = require("events").EventEmitter,
  util = require("util");

const FileController = function(url, path) {
  EventEmitter.call(this);

  this.url = url;
  this.path = path;
};

FileController.prototype.downloadFile = function() {
  if (this.url) {
    let file = fs.createWriteStream(this.path);

    file.on("finish", function() {
      file.close(function() {
        this.emit("downloaded");
      });
    }).on("error", function(err) {
      this.handleDownloadError(err, "file-error");
    });

    // Download the file.
    request.get(this.url)
      .on("response", function(res) {
        if (res.statusCode == 200) {
          res.pipe(file);
        } else {
          fs.unlink(this.path);
        }

        this.emit("stream", res);
      })
    .on("error", function(err) {
      this.handleDownloadError(err, "request-error");
    });
  }
};

FileController.prototype.handleDownloadError = function(err, type) {
  fs.unlink(this.path);
  this.emit(type, err);
};

util.inherits(FileController, EventEmitter);

module.exports = FileController;

And then here's the relevant parts of my test code where I instantiate an object:

beforeEach(function() {
  let url = "http://example.com/logo.png",
    path = config.downloadPath + "/cdf42c077fe6037681ae3c003550c2c5";

  fileController = new FileController(url, path);
  // Outputs 'undefined'.
  console.log(fileController.downloadFile);
});

When I make the call to new FileController(url, path) , it is not attaching the downloadFile method that I've attached to the prototype. Instead, trying to call that function gives me fileController.downloadFile is not a function .

Any thoughts as to where the problem lies?

Thx!

This has nothing to do with mocha. You need to inherit before defining your own prototype methods.

From docs

Inherit the prototype methods from one constructor into another. The prototype of constructor will be set to a new object created from superConstructor.

util.inherits(FileController, EventEmitter);

FileController.prototype.downloadFile = function() {}

UPD As for new versions of node. It now sets ctor.prototype prototype so the order doesn't matter anymore.

exports.inherits = function(ctor, superCtor) {

  //...Args check

  ctor.super_ = superCtor;
  Object.setPrototypeOf(ctor.prototype, superCtor.prototype);
};

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