Test the submitForm() method

There are two scenarios we need to cover in the test. One is a successful registration and the other is a failed registration. Our application behaves differently in these two scenarios. It is better that we use a separate test for each scenario.

In the test for the submitForm() method, we will isolate the method itself from its dependency, registrationService, by creating a mock of the service. In this way, we can define the behavior of the dependency and make sure it won't affect the test result. Using Jest, we will need to put the mocks in a folder named __mocks__ inside the same directory as the dependency. And the following are the paths of registrationService and its mock:

frontend/src/services/registration/index.js
frontend/src/services/registration/__mocks__/index.js

Here is how the mock looks:

export default {
register (detail) {
return new Promise((resolve, reject) => {
detail.emailAddress === 'sunny@local'
? resolve({result: 'success'})
: reject(new Error('User already exist'))
})
}
}

As you can see, the mock has exactly the same API as registrationService. The register() method is promise-based and its implementation is quite simple. When the email address is sunny@local, we will have a success registration; otherwise, we will have a failed registration with the error message User already exists.

Now, let's change the RegisterPage.spec.js to test specification the following:

import { mount, createLocalVue } from '@vue/test-utils'
import VueRouter from 'vue-router'

// Adding Vue Router to the test so that
// we can access vm.$router
const localVue = createLocalVue()
localVue.use(VueRouter)
const router = new VueRouter()

// Mock dependency registratioService
jest.mock('@/services/registration')

describe('RegisterPage.vue', () => {
...
beforeEach(() => {
wrapper = mount(RegisterPage, {
localVue,
router
})
...
})

afterAll(() => {
jest.restoreAllMocks()
})
...
})

As you can see, we import the createLocalVue function from vue-test-utils. As its name suggests, this function creates a local Vue class so that the changes we make to this local Vue class won't affect the actual global Vue class. We also import VueRouter. Inside the beforeEach() method,  we provide both the local Vue instance and the router instance to the mount function for creating wrapper. The reason we need the router instance here is that we will use it to check whether redirection to the login page has occurred or not.

We use jest.mock('@/services/registration') to prepare the mock of registrationService that we created earlier. We restore registrationService by calling jest.restoreAllMocks() inside afterAll(), which will be invoked once all of the tests in this file have finished their execution.

Now, let's implement the test that is used to verify a successful registration. The test method looks like the following:

it('should register when it is a new user', () => {
const stub = jest.fn()
wrapper.vm.$router.push = stub
wrapper.vm.form.username = 'sunny'
wrapper.vm.form.emailAddress = 'sunny@local'
wrapper.vm.form.password = 'Jest!'
wrapper.vm.submitForm()
wrapper.vm.$nextTick(() => {
expect(stub).toHaveBeenCalledWith({name: 'LoginPage'})
})
})

As you can see, we stub the push() method of vm.$router so that we can check whether the redirect happened or not. After providing values to the data model, we call the wrapper.vm.submitForm() method to trigger the form submit. Since the registrationService.register() method is promise-based, we need to wrap the expect assertion inside vm.$nextTick(), otherwise the assertion would always fail.

The following is the test to verify a failed registration:

it('should fail it is not a new user', () => {
// In the mock, only sunny@local is new user
wrapper.vm.form.emailAddress = 'ted@local'
expect(wrapper.find('.failed').isVisible()).toBe(false)
wrapper.vm.submitForm()
wrapper.vm.$nextTick(null, () => {
expect(wrapper.find('.failed').isVisible()).toBe(true)
})
})

As mentioned, when a registration fails, we will display an error message. So, in this test, at the beginning, we verify that the error message is not visible before the submitForm() method is invoked. Inside vm.$nextTick(), we verify that the error message is visible.

By now, we have finished the tests of the submitForm() method. Let's implement the submitForm() method itself now.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.107.31