How to expect the number of dom in karma+enzyme - karma-jasmine

I follow this link 'https://github.com/airbnb/enzyme/blob/master/docs/api/shallow.md' to write an unit test as below:
import { shallow } from 'enzyme';
import React from 'react';
import TextField from 'material-ui/TextField'
describe('Question Test Suite', () => {
it('should render one <TextField/> components', () => {
const wrapper = shallow(<QuestionForm />, { context: {router: {} }});
expect(wrapper.find(TextField)).to.have.length(1);
});
});
when run the test case I got below error:
TypeError: expect(...).length is not a function
TypeError: Cannot read property 'have' of undefined
What wrong with my test case? Is there anything I am missing there?

Your syntax is wrong.The below syntax should work fine.
expect(wrapper.find('TextField').length).toEqual(1);

Related

react-redux useSelector() hook not working

I am new to React Native Programming. So, please tell me in detail. thank you.
calling use Selector
I am calling use Selector inside my functional component like this:
import { useDispatch, useSelector } from 'react-redux';
const AddAddressScreen = ({ navigation }) => {
const dispatch = useDispatch();
const data = useSelector(state => state);
console.log(data + "happy Coding");
return (
<View style={styles.container}>
<View>
);
}
export default AddAddressScreen;
My reducer looks like this
case types.API_LOGIN_SUCCESS:
if (action.result.result.mobile_verified === false) {
return {
...state,
onLoad: false,
result: action.result,
status: action.status,
error: null,
navigation: action.navigation.navigate("VerifyMNO")
};
} else {
return {
...state,
onLoad: false,
result: action.result,
status: action.status,
error: null,
navigation: action.navigation.navigate("AddAddress")
};
}
here my mobile number is verified so I move to the address screen.
where I use Use Selector which gives me an error. while I remove above two lines my code runs successfully.
My saga looks like this
export function* watchLoginUserInfo() {
yield takeLatest(types.LOGIN_USER, loginApiSaga)
}
My root saga
import { all, fork } from 'redux-saga/effects';
import { watchLoginUserInfo, } from './authenticationSagas';
function* rootSaga() {
yield all([
watchLoginUserInfo(),
])
}
export default rootSaga;
My Store looks like this
import {createStore, applyMiddleware} from 'redux';
import rootReducer from '../redux/reducers/root-reducer.js'
import createSagaMiddleware from 'redux-saga';
import rootSaga from '../redux/sagas/rootSaga';
const sagaMiddleware = createSagaMiddleware();
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware));
sagaMiddleware.run(rootSaga);
export {store};
when ever I use use Selector hook in my code it gives me the following error.
error 1
error 2, 3, 4
Use the select effect from redux-saga inside of a reducer: https://redux-saga.js.org/docs/api/#selectselector-args
For example const selectedState = yield select(state => state);.
The useSelector hook is for use inside of a function component.
EDIT: since the above doesn't seem to be the issue, I think the issue is that you're calling navigation functions from within your reducer. Reducer code can have no side effects, so you can't call navigation.navigate(...) from within the reducer. This will need to happen in the saga code instead. It might be able to be done in the loginApiSaga or in a dedicated saga that is triggered by API_LOGIN_SUCCESS.

How to test a vue method with mocha Chai

This is MOCHA CHAI unit test : users.spec.js :
import { expect } from "chai";
import { shallowMount } from "#vue/test-utils";
import Users from "#/components/Users.vue";
const wrapper = shallowMount(Users);
describe("Users test", () => {
it("Displays nice hello message", () => {
expect(wrapper.vm.$data.msg).to.equal("Welcome to Crypto Info");
});
it("users model is an array", () => {
expect(wrapper.vm.$data.users).to.be.an("array");
});
it("getUsers() to be a function", () => {
expect(wrapper.vm.$methods.getUsers()).to.be.a("function");
});
});
I can't find the correct syntax for my third test . I've tried plenty of things . $methods.getUsers() is not working .
1) Users test
getUsers() to be a function:
TypeError: Cannot read property 'getUsers' of undefined
at Context.it (dist\js\webpack:\tests\unit\users.spec.js:15:1)
Could you please help me?
Thank you .
The method would simply be defined as a property of the wrapper.vm, so you could verify the method exists with:
expect(wrapper.vm.getUsers).to.be.a("function")
Could you do something like
const result = typeOf wrapper.vm.$methods.getUsers();
Then test the result is a string with value "function"?
expect(result).to.equal("function");
Is that any use to you?

How to simulate calling a utility function using jest?

I'm testing a utility function that returns an integer, I'm trying to simulate calling it, but I can't find the right way to do so even after hours of googling.
I've also tried spyOn() and it didn't seem to work.
Authentication.js
export function auth(username) {
AsyncStorage.getItem('#app:id').then((id) => {
if (id === username) {
return 1;
}
return 0;
});
}
Authentication.test.js
import 'react-native';
import React from 'react';
import renderer from 'react-test-renderer'; // Note: test renderer must be required after react-native.
import mockAxios from 'axios';
import mockAsyncStorage from '#react-native-community/async-storage';
import auth from '../App/Utils/Authorization';
test('should check whether the user whose username is entered as a paramter is the same as the user logged in the application', () => {
auth = jest.fn();
expect(auth).toHaveReturned();
expect(mockAsyncStorage.getItem).toHaveBeenCalledTimes(1);
expect(mockAsyncStorage.multiRemove).toHaveBeenCalledWith('#app:id');
});
I expected a simulation of calling auth() and a successful test, instead, I'm getting an error "auth" is read-only as an output whenever running yarn test.
You are reassigning the imported member auth and not using jest.fn() in the way that is supposed to work. Calling the jest mock function would return undefined, instead with mockFn.mockImplementation(fn) you could bind your function to the mock and test that it's being called or returning some expecting value.
import auth from '../App/Utils/Authorization';
test('Test auth', () => {
const mockAuth = jest.fn().mockImplementation(auth);
mockAuth();
expect(mockAuth).toHaveBeenCalled();
}
You can validate the output of your function checking mockFn.mock.results, which stores the results of every call made over your call function.
test('when user is provided', () => {
mockAuth({ user: {id: 'test', name: 'test'} });
expect(mockAuth).toHaveBeenCalled();
const result = mockAuth.mock.results[0].value;
expect(result).toBe(1);
});

How to unit test Vue.js components that use nuxt-i18n

If I try to run the thing below (with yarn run jest), I get TypeError: _vm.$t is not a function, because SearchField is using a translation ("$t('search')").
import { mount } from "#vue/test-utils";
import SearchField from "#/components/ui/SearchField";
describe("SearchField", () => {
const wrapper = mount(SearchField);
it("renders correctly", () => {
expect(wrapper.element).toMatchSnapshot();
});
});
If I add the following three lines at the beginning, I get TypeError: Cannot read property '_t' of undefined instead.
import Vue from "vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
nuxt-i18n is an external library, not your own code, so the test good practices ask us to just mock the translation library and its needed functions ($t in this case).
The following code should solve your problem:
describe("SearchField", () => {
const wrapper = mount(SearchField);
it("renders correctly", () => {
mocks: {
$t: (msg) => msg
}
expect(wrapper.element).toMatchSnapshot();
});
});
More information on this approach can be found here.

Jest + Nuxt + Nuxt-Fire is failing in test suite

I'm using Nuxt with Nuxt-Fire (https://github.com/lupas/nuxt-fire)
When I launch my test I get this error [Vue warn]: Error in config.errorHandler: "TypeError: Cannot read property 'ref' of undefined"
This is happening because of this section in my App
mounted() {
this.initiate(window.instaroomId)
let connected = this.$fireDb.ref(".info/connected")
this.getConnection(connected)
},
It looks like the this.$fireDb is not called. The module is normally loaded in nuxt.config.js. How can I make this work?
If you want to test, that this.$fireDb.ref(".info/connected") was called you can mock it like this:
import { shallowMount } from '#vue/test-utils'
import SomeComponent from '#/components/SomeComponent/SomeComponent.vue'
let wrapper
describe('SomeComponent.vue Test', () => {
beforeEach(() => {
wrapper = shallowMount(SomeComponent, {
mocks: {
$fireDb: {
ref: jest.fn()
}
}
})
})
it('$fireDb.ref was called', () => {
expect(wrapper.vm.$fireDb.ref).toBeCalled()
expect(wrapper.vm.$fireDb.ref).toBeCalledWith('.info/connected')
})
})
Or if you want the test just to pass created() hook and test another functionality you can just mock $fireDb.ref without testing that it was called.