Mocking APIs helps in situations where we only have the front-end of the application or we are dependant on third-party APIs. Mocking enables one to decouple the back-end from the front-end which results in faster execution of tests. In cypress, we can mock any XHR (XML HTTP Request) using cy.intercept(). Let’s further deep dive by automating the below scenario –
1. Go to https://angular.realworld.io/
2. Now there are two XHR requests that are triggered when we open this page – Tags and Article Feed.
3. We will intercept the tags requests and instead of the original list of Tags, we will pass two completely new tags – cypress, selenium, and verify them in the UI.
4. We will intercept the Article Feed request and instead of the original list of articles, we will pass just one article with the changed username, description, and the number of likes and then verify all of them in UI.
Step 1: Open https://angular.realworld.io/ and check the XHR requests from the dev tools.
When we open the tags XHR and check the response, we get the list of tags.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | { "tags":[ "", "", "", "", "", "", "", "", "", "", "HuManIty", "HuManIty", "Gandhi", "HITLER", "SIDA", "BlackLivesMatter", "BlackLivesMatter", "test", "dragons", "butt" ] } |
Instead of the above response, we want that whenever the Tags XHR request is called the below response should be passed to the UI.
1 2 3 4 5 6 | { "tags":[ "cypress", "selenium" ] } |
We will add this to our fixtures files (tags.json).
Similarly, when we open the article feed XHR and check the response, we get the list of articles.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | { "articles":[ { "title":"Brand new article2", "slug":"brand-new-article2-kq4e63", "body":"Very, very long description", "createdAt":"2021-02-13T17:02:19.891Z", "updatedAt":"2021-02-13T17:02:19.891Z", "tagList":[ ], "description":"Subtitle", "author":{ "username":"admintest1234", "bio":null, "image":"https://static.productionready.io/images/smiley-cyrus.jpg", "following":false }, "favorited":false, "favoritesCount":0 }, { "title":"Brand new article2", "slug":"brand-new-article2-w1cju5", "body":"Very, very long description", "createdAt":"2021-02-13T17:00:28.016Z", "updatedAt":"2021-02-13T17:00:28.016Z", "tagList":[ ], "description":"Subtitle", "author":{ "username":"admintest1234", "bio":null, "image":"https://static.productionready.io/images/smiley-cyrus.jpg", "following":false }, "favorited":false, "favoritesCount":0 }, { "title":"Brand new article2", "slug":"brand-new-article2-172cnz", "body":"Very, very long description", "createdAt":"2021-02-13T16:55:41.169Z", "updatedAt":"2021-02-13T16:55:41.169Z", "tagList":[ ], "description":"Subtitle", "author":{ "username":"admintest1234", "bio":null, "image":"https://static.productionready.io/images/smiley-cyrus.jpg", "following":false }, "favorited":false, "favoritesCount":0 }, { "title":"Sample article", "slug":"sample-article-7d2w18", "body":"This can be used for my jmeter practice also at some point", "createdAt":"2021-02-13T16:54:50.655Z", "updatedAt":"2021-02-13T16:54:50.655Z", "tagList":[ ], "description":"This is a sample article", "author":{ "username":"Jeffrey William", "bio":"This is a sample update", "image":"https://static.productionready.io/images/smiley-cyrus.jpg", "following":false }, "favorited":false, "favoritesCount":0 } ] } //I have removed some of the entries as the response was long. |
Instead of the above response, we want that whenever the Article XHR request is called the below response should be passed to the UI.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | { "articles":[ { "title":"Hi", "slug":"hi-5h5nba", "body":"testing", "createdAt":"2020-09-26T03:18:26.635Z", "updatedAt":"2020-09-26T03:18:26.635Z", "tagList":[ ], "description":"This is a test description", "author":{ "username":"testersdock", "bio":null, "image":"https://static.productionready.io/images/smiley-cyrus.jpg", "following":false }, "favorited":false, "favoritesCount":10 } ], "articlesCount":500 } |
In the above response, we are passing only one article, with username as ‘testersdock’, description as ‘This is a test description’ and favoritesCount as ’10’. We will add this to our fixtures files (articlefeed.json).
Step 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | describe('Example to demonstrate API Mocking in Cypress using cy.intercept', () => { beforeEach(() => { cy.intercept('GET', '**/tags', { fixture: 'tags.json' }) cy.intercept('GET', '**/articles*', { fixture: 'articlefeed.json' }) cy.visit('https://angular.realworld.io/') }) it('Mock the Tags from the API Response and then validate on UI', () => { cy.get('.tag-list', { timeout: 10000 }) .should('contain', 'cypress') .and('contain', 'selenium') }) it('Mock the Article feed from the API Response and then validate on UI', () => { cy.get('app-favorite-button.pull-xs-right').contains('10') cy.get('.author').contains('testersdock') cy.get('.preview-link > p').contains('This is a test description') }) }) |
1 2 3 4 5 | beforeEach(() => { cy.intercept('GET', '**/tags', { fixture: 'tags.json' }) cy.intercept('GET', '**/articles*', { fixture: 'articlefeed.json' }) cy.visit('https://angular.realworld.io/') }) |
cy.intercept(‘GET’, ‘**/tags’, { fixture: ‘tags.json’ }) makes sure that that whenever the Tags api endpoint is called, the response that is passed to the UI would be from tags.json fixture file.
cy.intercept(‘GET’, ‘**/articles*’, { fixture: ‘articlefeed.json’ }) makes sure that that whenever the articles api endpoint is called, the response that is passed to the UI would be from articlefeed.json fixture file.
1 2 3 4 5 6 | it('Mock the Tags from the API Response and then validate on UI', () => { cy.get('.tag-list') .should('contain', 'cypress') .and('contain','selenium') }) |
This will check that now there are only two tags displayed in the UI – cypress and selenium.
1 2 3 4 5 | it('Mock the Article feed from the API Response and then validate on UI', () => { cy.get('app-favorite-button.pull-xs-right').contains('10') cy.get('.author').contains('testersdock') cy.get('.preview-link > p').contains('This is a test description') }) |
This will check that now instead of a list of article, there is only one article with favoritesCount as 10, username as testersdock and description as This is a test description.
Step 3: After successful execution:
Do check out 🙂
Github: https://github.com/alapanme/Cypress-Automation
All Cypress Articles: https://testersdock.com/cypress-tutorial/
Where is the mock done for images?
Thanks for your comment. This blog post doesn’t talk about mocking images.
Hi Alapan , Appreciate your effort on creating very good content ! Really help to learn and time saving when we read through.
I want to use fixtures whenever i get null response from api. for eg : to test particular scenario , i set data for few test but not for all. Whenever the original response is zero i need to use Mock. Can you help on this?
How we can use cy. intercept() for login