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

transcribe unusual spending kata from ES5 to ES6/babel #163

Closed
wpannell opened this issue Dec 12, 2016 · 8 comments
Closed

transcribe unusual spending kata from ES5 to ES6/babel #163

wpannell opened this issue Dec 12, 2016 · 8 comments

Comments

@wpannell
Copy link

wpannell commented Dec 12, 2016

This issue hampers the ideal ES6 workflow inspired by your Unusual Spending Kata in ES5.

(I get the following results whether I use named or default ES6 imports and exports.)

I can get to my first failing test – specifying ES6 named exports – like so:

//...unusual-spending.spec.js
import td from 'testdouble';

describe('unusualSpending() should', function() {
  it('interact correctly with fetch(), categorize() and notify()', function() {
    const fetch = td.replace('./fetch').fetch;
    const categorize = td.replace('./categorize').categorize;
    const notify = td.replace('./notify').notify;

    console.log(fetch); // { [Function: testDouble] toString: [Function] }
    console.log(categorize); // { [Function: testDouble] toString: [Function] }
    console.log(notify); // { [Function: testDouble] toString: [Function] }

    const dummyUserId = 'dummy-user-id';
    const dummyPaymentsResponse = 'dummy-payments-response';
    const dummyCategorizedPayments = 'dummy-categorized-payments';

    let unusualSpending;

    td.when(fetch(dummyUserId)).thenReturn(dummyPaymentsResponse);

    td.when(categorize(dummyPaymentsResponse)).thenReturn(
        dummyCategorizedPayments);

    unusualSpending = require('./unusual-spending').unusualSpending;
    unusualSpending(dummyUserId);

    td.verify(notify(dummyUserId, dummyCategorizedPayments));
  });
});

This forces me to build the following units – using ES6 named exports:

//...fetch.js
const fetch = () => {};
export {fetch};

//...categorize.js
const categorize = () => {};
export {categorize};

//...notify.js
const notify = () => {};
export {notify};

But the concrete unit does not get the ES6 named imports replaced with the test doubles configured in the test:

//...unusual-spending.js
import {fetch} from './fetch';
import {categorize} from './categorize';
import {notify} from './notify';

const unusualSpending = userId => {

  console.log(fetch); // [Function: fetch]
  console.log(categorize); // [Function: categorize]
  console.log(notify); // [Function: notify]

  const payments = fetch(userId);
  const categorizedPayments = categorize(payments);
  notify(userId, categorizedPayments);
};
export {unusualSpending};

What do you recommend?

I wish there was something like td.import('filespec') that I could use in the test like this:

    unusualSpending = td.import('./unusual-spending');

that would ensure the subject is configured with the test doubles from the test.

@wpannell
Copy link
Author

The code for working with default — as opposed to named — imports and exports, would look like this:

//...unusual-spending.spec.js

import td from 'testdouble';

describe('unusualSpending() should', function() {
  it('interact correctly with fetch(), categorize() and notify()', function() {
    const fetch = td.replace('./fetch').default;
    const categorize = td.replace('./categorize').default;
    const notify = td.replace('./notify').default;

    // ...

    unusualSpending = require('./unusual-spending').default;
    unusualSpending(dummyUserId);

    td.verify(notify(dummyUserId, dummyCategorizedPayments));
  });
});

//...fetch.js

const fetch = () => {};
export default fetch;

//...categorize.js

const categorize = () => {};
export default categorize;

//...notify.js

const notify = () => {};
export default notify;

//...unusual-spending.js

import fetch from './fetch';
import categorize from './categorize';
import notify from './notify';

const unusualSpending = userId => {
  // ...
};

export default unusualSpending;

@m0nq
Copy link

m0nq commented Dec 13, 2016

^bump. I've definitely noticed that td.replace() doesn't work correctly on my machine using the es6 syntax.

Would be awesome if I didn't have to necessarily make an object that my stubs were hanging off of in order to use them considering the es6 syntax and classes is kind of a cover all for the prototypical inheritance behind the scene to begin with.

@searls
Copy link
Member

searls commented Dec 13, 2016

Thanks to you both, I haven't lost track of this I just need to get time to reproduce and think through this issue and #159.

@wpannell
Copy link
Author

To work around this issue in ES6/babel, we're forced to stick to the require() and module.exports. The rest of ES6/babel works just fine for your ideal TDD workflow.

This is what I need, so, I'm closing this issue. It should be straightforward enough to factor in ES6 import/export once you've had a chance to look into it:

//...unusual-spending.js
const fetch = require('./fetch');
//...

//...fetch.js
const fetch = () => {};
module.exports = fetch;

//...unusual-spending.spec.js
const td = require('testdouble');

describe('unusual spending should', function() {
  it('interact with fetch, high-spending and notify', function(done) {
    const fetch = td.replace('./fetch');
    //...
    unusualSpending = require('./unusual-spending');
    //...
  });
});

@searls
Copy link
Member

searls commented Dec 14, 2016

If you don't mind I'd like to leave this open so I can better understand it -- feel free to unsubscribe though!

@searls searls reopened this Dec 14, 2016
@searls
Copy link
Member

searls commented Dec 14, 2016

Hey Wil, I just set things up exactly how you had them in your first message and it completely worked for me. I didn't experience the issue of the subject not receiving the fakes.

Mocha generated this output:

  unusualSpending() should
{ [Function: testDouble] toString: [Function] }
{ [Function: testDouble] toString: [Function] }
{ [Function: testDouble] toString: [Function] }
{ [Function: testDouble] toString: [Function] }
{ [Function: testDouble] toString: [Function] }
{ [Function: testDouble] toString: [Function] }
    ✓ interact correctly with fetch(), categorize() and notify()


  8 passing (119ms)

I've pushed this up to a branch for you to play with in examples/babel. If you run npm it you should see it work like I am. Let me know if I'm missing something here!

Branch here, named 163-wil-example:
https://github.com/testdouble/testdouble.js/tree/163-wil-example/examples/babel

@wpannell
Copy link
Author

Awesome.

You missed nothing. I missed everything.

I had stray td.replace('./such-and-such.js) strewn here-and-there in my code. Might've even had a stray require('./unusual-spending.js') in there too, although I cannot recall for sure now.

Your stuff works great for ES6/babel. I recommend you close this because it is not your issue.

@searls
Copy link
Member

searls commented Dec 14, 2016

Yay! Thanks a lot for giving such a detailed reproducible example so we could demonstrate that then! 💚

@searls searls closed this as completed Dec 14, 2016
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

3 participants