Skip to main content
Tweeted twitter.com/StackProgrammer/status/654066504544186368

It makes testing the library much simpler, because there isn't much to test.

This is a concrete case I'm dealing with in NodeNode.js:

That is trivial to test: injecting mocksmock objects or spies as the texCompiler and pdfMerger is a piece of cake because the function really doesn't do much at all. All I can test is that both functions are called in the right sequence.

This is the real thing, and it is a bigger pain to test. I have to mock child_process.spawn with a spy to make sure it gets called with the right arguments, but it doesn't actually do anything, because I don't want to actually merge any PDF file when running the tests and my mocks have to emit the right events so the function isn't stuck.

It makes testing the library much simpler because there isn't much to test.

This is a concrete case I'm dealing with in Node:

That is trivial to test: injecting mocks or spies as the texCompiler and pdfMerger is a piece of cake because the function really doesn't do much at all. All I can test is that both functions are called in the right sequence.

This is the real thing and it is a bigger pain to test. I have to mock child_process.spawn with a spy to make sure it gets called with the right arguments but doesn't actually do anything because I don't want to actually merge any PDF when running the tests and my mocks have to emit the right events so the function isn't stuck.

It makes testing the library much simpler, because there isn't much to test.

This is a concrete case I'm dealing with in Node.js:

That is trivial to test: injecting mock objects or spies as the texCompiler and pdfMerger is a piece of cake because the function really doesn't do much at all. All I can test is that both functions are called in the right sequence.

This is the real thing, and it is a bigger pain to test. I have to mock child_process.spawn with a spy to make sure it gets called with the right arguments, but it doesn't actually do anything, because I don't want to actually merge any PDF file when running the tests and my mocks have to emit the right events so the function isn't stuck.

Add markdown
Source Link
springloaded
  • 2.2k
  • 3
  • 14
  • 10

That is trivial to test: injecting mocks or spies as the texCompilertexCompiler and pdfMergerpdfMerger is a piece of cake because the function really doesn't do much at all. All I can test is that both functions are called in the right sequence.

It doesn't save me from testing my texCompilertexCompiler and pdfMergerpdfMerger functions eventually though. They look something like that:

This is the real thing and it is a bigger pain to test. I have to mock child_process.spawnchild_process.spawn with a spy to make sure it gets called with the right arguments but doesn't actually do anything because I don't want to actually merge any PDF when running the tests and my mocks have to emit the right events so the function isn't stuck.

That is trivial to test: injecting mocks or spies as the texCompiler and pdfMerger is a piece of cake because the function really doesn't do much at all. All I can test is that both functions are called in the right sequence.

It doesn't save me from testing my texCompiler and pdfMerger functions eventually though. They look something like that:

This is the real thing and it is a bigger pain to test. I have to mock child_process.spawn with a spy to make sure it gets called with the right arguments but doesn't actually do anything because I don't want to actually merge any PDF when running the tests and my mocks have to emit the right events so the function isn't stuck.

That is trivial to test: injecting mocks or spies as the texCompiler and pdfMerger is a piece of cake because the function really doesn't do much at all. All I can test is that both functions are called in the right sequence.

It doesn't save me from testing my texCompiler and pdfMerger functions eventually though. They look something like that:

This is the real thing and it is a bigger pain to test. I have to mock child_process.spawn with a spy to make sure it gets called with the right arguments but doesn't actually do anything because I don't want to actually merge any PDF when running the tests and my mocks have to emit the right events so the function isn't stuck.

Source Link
springloaded
  • 2.2k
  • 3
  • 14
  • 10

Doesn't dependency injection push the testing burden further down the chain?

I'm learning about dependency injection and while I can see the appeal of it when writing functional libraries, I fail to see how it solves anything when you'll also be the one using the libraries.

It makes testing the library much simpler because there isn't much to test.

But you will eventually have to test your injected function when you use the library and have to deal with mocking and stubbing functions from the standard library.

This is a concrete case I'm dealing with in Node:

function compile(options) {
  var files = options.files;
  var texCompiler = options.texCompiler;
  var pdfMerger = options.pdfMerger;

  return Promise.all(files.map(texCompiler(files)))
    .then(pdfMerger);
}

That is trivial to test: injecting mocks or spies as the texCompiler and pdfMerger is a piece of cake because the function really doesn't do much at all. All I can test is that both functions are called in the right sequence.

It doesn't save me from testing my texCompiler and pdfMerger functions eventually though. They look something like that:

var tex2Pdf = Promise.method(function tex2Pdf(tex_doc) {
    var latex_command = 'pdflatex';
    var pdf_output_filename = path.parse(tex_doc).name + '.pdf';
    var cmd = latex_command + ' ' + tex_doc;
    var options = {
      cwd: path.resolve(tex_doc, '..') // pdflatex will only look for custom
      // cls files in the cwd and includes relative to the cwd
    };
    child_process.spawn(cmd, options)
      .on('end', function() {
        console.log('tex2Pdf finish');
        debugger;
        return path.resolve(tex_doc, '..', pdf_output_filename);
      })
      .on('error', function(e) {
        throw e;
      });
});


var mergeTwoPdf = Promise.method(function mergeTwoPdf(pdf_files) {
  var output_file = randomId() + '.pdf';
  var cmd = 'gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=' + output_file + ' ' + pdf_files[0] + ' ' + pdf_file[1];
  child_process.spawn(cmd)
    .on('finish', function() {
      return output_file;
    })
  .on('error', function(e) {
    throw (e);
  });
});

This is the real thing and it is a bigger pain to test. I have to mock child_process.spawn with a spy to make sure it gets called with the right arguments but doesn't actually do anything because I don't want to actually merge any PDF when running the tests and my mocks have to emit the right events so the function isn't stuck.

These are problems I would have had if I didn't inject the dependency in my first snippet and used these functions instead. And it really feels like I'm pushing the problem further down without solving it.

Am I misunderstanding dependency injection? Am I doing it wrong?