Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to stub unzipper? #58

Closed
VictorCazanave opened this issue Apr 2, 2018 · 4 comments
Closed

How to stub unzipper? #58

VictorCazanave opened this issue Apr 2, 2018 · 4 comments

Comments

@VictorCazanave
Copy link

Hello,

I use unzipper in a node.js module and everything works well:

...
readableStream.pipe(unzipper.Parse())
    .on('entry', (entry) => {
        // Filter and write files like in the doc
        ...
    })
    .on('finish', () => {
        callback();
    });
...

Now I would like to unit test my module with Mocha/Sinon/Chai and avoid to really call unzipper using a stub (or something else).
I tried many things but I can't figure out how to handle events (entry and finish), so the callback() is never called and the test returns a timeout error.

Does anyone have an example of unit test with a "fake" unzipper?

PS: I know it's not really an issue, so if you think it's not relevant, fell free to close it.

@camlegleiter
Copy link

Seems like that's a bit of a hassle. Would it be easier to pull out each of your event handlers and test them more individually? Testing code like that feels like its closer to an "integration" test since you're verifying different units of work will work together, which would make more sense to actually use unzipper as part of the test.

@VictorCazanave
Copy link
Author

VictorCazanave commented Apr 3, 2018

I'm not an expert in testing, so I may have mixed unit and integration tests.
My event handlers are private methods and I didn't plan to test it (I know there is a debate about it).
Actually, the only thing I would like to test is the callback (with or without error):

if(isValid) {
    readableStream.pipe(unzipper.Parse())
        .on('entry', (entry) => {
            // Filter and write files like in the doc
            ...
        })
        .on('finish', () => {
            callback();
        });
} else {
    callback(new Error());
}

If stubbing unzipper is too complicated, I'll try to use it with a simple .zip file for my tests.

@VictorCazanave
Copy link
Author

Oops! My bad... Actually my first idea works well but I called the event emit at the wrong place 🤦‍♂️
Here is my solution:

describe('...', () => {
   let readableStream = null;
   let Parse = null;

   beforeEach(() => {
      readableStream = new stream.Readable({ read: () => null });
      Parse = sinon.stub(unzipper, 'Parse');
      Parse.returns(readableStream);
   });
   
   afterEach(() => {
      Parse.restore();
   });

   it('...', done => {
      myFunctionToTest(..., err => {
         expect(err).to.be.undefined;
         done();
      });
      readableStream.emit('finish');
   });
});

Sorry and thanks for you help @camlegleiter

@camlegleiter
Copy link

I was actually going to suggest doing something just like that: stub in your own stream implementation (Readable, PassThrough, etc.) as the returned value from unzipper and emit events to trigger different function calls. The only downside is because you're keeping your functions private it requires more setup and stubbing to test each private method instead of exposing them for testing by exporting the function separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants