'Stencil unit testing: How to mock initial state and load newSpecPage?
I am new to unit testing and planning to write unit test cases but not E-2-E for the below mentioned scenario and playgrounnd link for scenario is at the bottom.
Scenario:-
I have a @State
variable called "ifSuccessResponse"
with initial value set as false
.
When @State
variable "ifSuccessResponse"
is true
, green-div
loads.
When @State
variable "ifSuccessResponse"
is false
, red-div
loads.
- How to mock initial state to have
@State
variableifSuccessResponse
to have value set astrue
and then load the newSpecPage so that I can testgreen-div
is loaded.
- Is it possible to update the
@State
variableifSuccessResponse
after loading the page in Moc Doc usingnewSpecPage
. Curious to know whether we can do this like how we can do inenzyme
library usingsetState method
.
Playground-link
:
https://webcomponents.dev/edit/Cbr1NS2QTrvC5scsmFZQ/src/index.stories.tsx
Solution 1:[1]
Instead of trying to mock State directly (by definition it is internal to component, otherwise you would/should use @Prop), you should find a way to get into the logic that exercise setting that state. Looking at the variable name, your component probably make call to some underlying API or service? If so, I would strongly recommend you to mock request/response to that service and then manipulate the State that way.
I use "fetch-mock" (https://www.npmjs.com/package/fetch-mock) to do this.
When you are using newSpecPage, you are dealing with DOM element so at that level, you want to minimize exposing internal logic like that so that you are actually testing how component is used. If you have complex logic, you could easily write unit test to test such function as well.
Solution 2:[2]
After creating the newSpecPage, you can access its contents. Try writing some console logs in your tests to see what you are working with.
For example:
console.log(page.root);
console.log(page.rootInstance);
console.log(page.root.outerHTML);
If you want to access or change a @State(), you can do that as follows
page.rootInstance.ifSuccessResponse = true
So the full test will look as follows
it('should show the green state', async () => {
const page = await newSpecPage({
components: [MyParentComponent],
template: () => <my-parent-component></my-parent-component>,
});
page.rootInstance.ifSuccessResponse = true;
const divEl = page.root.shadowRoot.querySelector('#green-div');
expect(divEl.innerHTML).toEqual('My favorite color is green');
});
Unfortunately I'm not able to run your playground project, so I hope I did it correctly. I also edited your test name slightly to make it a readable sentence. I would advise you to name your tests likewise.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | tomokat |
Solution 2 | richardec |