8000 Added README for provide/inject. resolves #2 · mcibique/vue-testing-examples@dd2a703 · GitHub
[go: up one dir, main page]

Skip to content

Commit dd2a703

Browse files
committed
Added README for provide/inject. resolves #2
1 parent 85ab896 commit dd2a703

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ Topics already covered:
4141
* [Using flush-promises vs Vue.nextTick()](#using-flush-promises-vs-vuenexttick)
4242
* [Testing navigation guards](#testing-navigation-guards)
4343
* [beforeRouteEnter](#beforerouteenter)
44+
* [Testing provide/inject](#testing-provideinject)
45+
* [Testing component that injects values](#testing-component-that-injects-values)
46+
* [Testing component that provides values](#testing-component-that-provides-values)
4447

4548
## Testing pyramid, dumb vs smart components, mount vs shallow
4649

@@ -1702,3 +1705,100 @@ it('should trigger beforeRouteEnter event', function () {
17021705
```
17031706

17041707
This approach requires a knowledge about VUE and router internals and **can stop working** after every minor refactoring done by the VUE team. I do not recommend to use it unless guys from VUE provide some helper function in [@vue/test-utils](https://github.com/vuejs/vue-test-utils) library for setting it up using cleaner way.
1708+
1709+
## Testing provide/inject
1710+
1711+
_NOTE_: Before you even start developing your components using `provide`/`inject`, please consider if you really need them. It is mentioned in [the official documentation](https://vuejs.org/v2/api/#provide-inject) that this feature is suitable only for certain scenarios. Also consider that both, `provide` and `inject` and not [reactive](https://vuejs.org/v2/guide/reactivity.html#ad), which only introduces limitation to the development that you have to keep in mind. Using "traditional" [one-way data flow](https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow) between components may be more appropriate for your use case.
1712+
1713+
For the testing purposes, let's have three components which communicate using `provide`/`inject`:
1714+
1715+
```html
1716+
<my-checkbox-list>
1717+
<my-checkbox-list-status></my-checkbox-list-status>
1718+
<my-checkbox v-model="value1">Checkbox 1</my-checkbox>
1719+
<my-checkbox v-model="value2">Checkbox 2</my-checkbox>
1720+
<my-checkbox v-model="value3">Checkbox 3</my-checkbox>
1721+
</my-checkbox-list>
1722+
```
1723+
1724+
... where `my-checkbox-list` is a wrapper providing an API for `my-checkbox`es to tell the list they are checked or not, and the `my-checkbox-list-status` is a component for displaying nice message to the user how many checkboxes have already been checked, e.g. `"2 out of 3 item(s) have been selected."`
1725+
1726+
### Testing component that injects values
1727+
1728+
For a component that only injects values we can use [provide option](https://vue-test-utils.vuejs.org/api/options.html#provide) for `mount` function:
1729+
1730+
```js
1731+
beforeEach(function () {
1732+
this.mountMyCheckboxListStatus = function (myCheckboxListMock, options) {
1733+
let provide = { "checkboxList": myCheckboxListMock };
1734+
let wrapper = mount(MyCheckboxListStatus, { provide, ...options });
1735+
return new MyCheckboxListStatusPageObj(wrapper);
1736+
};
1737+
});
1738+
1739+
it('should render the message', function () {
1740+
let myCheckboxListMock = { numberOfItems: 6, numberOfSelectedItems: 3 };
1741+
let myCheckboxListStatus = this.mountCheckboxListStatus(myCheckboxListMock);
1742+
expect(myCheckboxListStatus.message).to.equal("3 out of 6 item(s) have been selected");
1743+
});
1744+
```
1745+
1746+
### Testing component that provides values
1747+
1748+
For a component that provides values is better to use integration tests and test all of their interactions together.
1749+
1750+
```js
1751+
beforeEach(function () {
1752+
this.mountMyCheckboxList = function (template, options) {
1753+
// we are going to mount a string template, thus we need to convert it into something that Vue can understand:
1754+
let Wrapper = Vue.extend({
1755+
...compileToFunctions(template),
1756+
components: { MyCheckboxList, MyCheckbox, MyCheckboxListStatus }
1757+
});
1758+
1759+
let wrapper = mount(Wrapper, { ...options });
1760+
return new MyCheckboxListPageObj(wrapper);
1761+
};
1762+
});
1763+
1764+
describe('when there are checkboxes in the list', function () {
1765+
beforeEach(function () {
1766+
// instead of testing individual components, create a template with all of them
1767+
this.myCheckboxList = this.mountMyCheckboxList(
1768+
`<my-checkbox-list>
1769+
<my-checkbox-list-status></my-checkbox-list-status>
1770+
<my-checkbox v-model="checkbox1">Checkbox 1</my-checkbox>
1771+
</my-checkbox-list>`,
1772+
{
1773+
data () {
1774+
return { checkbox1: false };
1775+
}
1776+
}
1777+
);
1778+
});
1779+
1780+
it('should render the checkbox list status', function () {
1781+
// test the initial status of the my-checkbox-list-status component
1782+
expect(this.myCheckboxList.status.text()).to.equal('You selected 0 item(s).');
1783+
});
1784+
1785+
it('should render checkboxes', function () {
1786+
// test the initial status of the my-checkbox component
1787+
expect(this.myCheckboxList.checkboxes.length).to.equal(1);
1788+
expect(this.myCheckboxList.checkboxes[0].isChecked).to.be.false;
1789+
});
1790+
1791+
describe('and the user changes the checkbox value', function () {
1792+
beforeEach(function () {
1793+
// clicking the my-checkbox should trigger the provide API in the parent my-checkbox-list.
1794+
this.myCheckboxList.checkboxes[0].check();
1795+
return Vue.nextTick();
1796+
});
1797+
1798+
it('should update the message in the checkbox list status', function () {
1799+
// the change in the parent should appear in the my-checkbox-list-status component
1800+
expect(this.myCheckboxList.status.text()).to.equal('You selected 1 item(s).');
1801+
});
1802+
});
1803+
});
1804+
```

TODO.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
1. Testing directive
66
1. Writing complex integration test for a component
77
1. Mocking router
8-
1. Inject/Provide
98
1. Scoped slots
109
1. Inversify and mocking router/store in tests
1110
1. Test coverage

0 commit comments

Comments
 (0)
0