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

Privatized stamp with stubs/fakes #47

Open
MaximusHaximus opened this issue Jul 13, 2018 · 5 comments
Open

Privatized stamp with stubs/fakes #47

MaximusHaximus opened this issue Jul 13, 2018 · 5 comments

Comments

@MaximusHaximus
Copy link

MaximusHaximus commented Jul 13, 2018

Howdy,
I'm running into some problems with stubbing methods on stamps that have been privatized. In particular, because referencing the injected method always references the PROXY function, there's no way to access the stubs properties. It'd be nice to be able to reference the stubs on their location since they are not private-ized and it's counter intuitive to not be able to access properties on the public methods. Not sure the best way to go about achieving that goal. For now I am storing my stubs in a local closure, then referencing them from their local closure variables. It'd be nicer to be able to reference the functions directly on the object. Open to any alternative composition patterns too, if there's a better way to accomplish this.

const Configure = require('@stamp/configure');
const stampit   = require('@stamp/it');
const sinon     = require('sinon');

const exampleStamp = stampit.compose(Configure)
  .methods({ myMethod() { return true; } });

const exampleStampInstance = exampleStamp();

const exampleMethodResult = exampleStampInstance.myMethod();
console.log(exampleMethodResult); // true

const myStub       = sinon.fake.returns(false);
const stubbedStamp = exampleStamp.methods({ myMethod: myStub });

const stubbedStampInstance = stubbedStamp();

const stubbedMethodResult = stubbedStampInstance.myMethod();

console.log(stubbedMethodResult); // false -- fake was called as expected (good!)
console.log('myStub.called', myStub.called); // true -- the stub logged the call

console.log('stubbedStampInstance.myMethod.called', stubbedStampInstance.myMethod.called); // undefined (should be true, not intuitive at all)
@koresar
Copy link
Member

koresar commented Jul 14, 2018

Hello there! 👋

For now I'd like to share what happened to me since I started doing stamps.

I used to use sinon a lot. Until I met stamps. Since then I do not use sinon. When my projects are using stamps the sinon is not needed.


There are two quick solutions though.

  1. Avoid privatisation by adding .noProvatize():
const exampleStamp = stampit.compose(Configure.noPrivatize())
  .methods({ myMethod() { return true; } });
  1. Or do not use sinon:
let called = 0;
exampleStamp.methods({ myMethod() {
  called += 1;
  return false;
} });

const stubbedStampInstance = stubbedStamp();

const stubbedMethodResult = stubbedStampInstance.myMethod();
console.log(called); // 1

If none of the above suffice feel free to ask further.

@MaximusHaximus
Copy link
Author

Understood that I could write my own equivalent of Sinon, but then I am re-writing a ton of assertions, especially if I want to assert against calledWith etc.

This is a more general problem with the Privatize stamp in that you cannot access ANY properties on public functions due to the method of proxying, my Sinon use case is just the first one I ran into :)

@koresar
Copy link
Member

koresar commented Jul 14, 2018

I hope to rewrite the Privatize when ES2018 Privates is released: https://github.com/tc39/proposal-private-methods#private-methods-and-fields
It's gonna be hard though. :)

@Deadarius
Copy link

@MaximusHaximus I use next pattern:

  • stampFolder
    • stamp.js <- actual implementation with public properties/methods that can be tested
    • index.js <- stamp with privatize composed on top of stamp.js, this is what actually being imported by other modules.

P.S. hehe, what an encounter, brother.

@koresar
Copy link
Member

koresar commented Aug 7, 2018

Looks like the Privatize can be implemented without a proxy-object. But with proxy-Proxy. 😂
https://medium.com/dailyjs/how-to-use-javascript-proxies-for-fun-and-profit-365579d4a9f8

This would allow privatizing only the necessary properties, not all of them!
Also, good for performance constrained applications.

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