ionic-team/stencil-state-tunnel

Can I override props injected by a tunnel?

sslotsky opened this issue · 2 comments

Say I have a component,

@Component ({ tag: 'my-message' })
export class MyMessage {
  @Prop() message: string;

  render() {
    return <p>{this.message}</p>;
  }
}

Tunnel.injectProps(MyMessage, ['message']);

Now let's say that the tunnel provides a default value:

export default createProviderConsumer<State>(
  {
    message: "Hello world!",
  },
  (subscribe, child) => <context-consumer subscribe={subscribe} renderer={child} />
);

Should I be able to override the message like this:

const foo = document.createElement('my-message'');
foo.message = "It's a new day!";
document.body.appendChild(foo);

This is a simplified example of course, but I'm finding that I'm not able to do this in my component, and it would be really helpful for testing purposes.

Any update on this? Does it work this way by design? It's still making testing rather difficult for me. If I want to provide my own data to the component for testing, it seems I either need a way to fake the provider, or I need my component to do nothing except pass the tunnel data to a child component that does all the rendering, and test that child component instead. Your thoughts would be greatly appreciated!

@sslotsky We ran into a similar issue and were mocking things like crazy in order to mitigate. That behavior started for us when we migrated to stencil 1.12.
In the end, the issue was solved by writing the tests in spec.tsx, like the generated boilerplate test files of stencil look like. Somehow then the props injected are getting interpreted over the state-tunnels defaults in the tests.

TL;DR
If you have problems unit testing components that also get props injected via state-tunnel, rename that test file from spec.ts to spec.tsx and see if it works. If it not works consider if the stencil store is a better option for you.