I am developing a React application with jest and TypeMoq.
I can't test the negative path of a decision tree when the mocked call is a method on the object which needs to be undefined. Is there a method on TypeMoq that can help me verify that the provided method is not called?
type TopicComponentProps = {
topic: Topic
history?: History<any>
}
export const TopicComponent = ({topic, history} : TopicComponentProps) => {
const { Id, Name } = topic;
const filterTopic = () => {
if (history) { // <-- this is my problem
history.push(`/topic/overview/${Id}`);
}
}
return(
<Fragment>
<span
style={topicStyle}
onClick={() => filterTopic()}
className="topic">
{Name}
</span>
</Fragment>
)
}
The positive test case looks like this:
it('should trigger the navigation when clicked', () => {
const mockHistory = Mock.ofType<History<any>>();
const wrapper = mount(
<TopicComponent topic={testTopic} history={mockHistory.object} />
);
wrapper.simulate('click');
mockHistory.verify(x => x.push(It.isAnyString()), Times.once());
});
How do I setup the mock object, so i can test that no navigation happens when no history is provided?
it('should not trigger the navigation when history is undefined', () => {
let mockHistory = Mock.ofType<History<any>>();
???
const wrapper = mount(
<TopicComponent topic={testTopic} history={???} />
);
wrapper.simulate('click');
mockHistory.verify(x => x.push(It.isAnyString()), Times.never());
});
Related
I am using function component where is there is a arrow function.
const handleOnConfig = (cfg) => {
const layout = { ...config };
setConfig(layout);
};
Now, I want to write unit test for that function.
So, I did following in my test file. I used
beforeEach(() => {
let props = {user:user}
view = shallow(<Views {...props} />).instance();
});
test('should call config change call back', () => {
const handleOnConfig = jest.spyOn(view,'handleOnConfig').mockImplementation(() => config);
expect(handleOnConfig).toHaveBeenCalledTimes(1);
});
But, this test case gives error:
TypeError: Cannot read property 'handleOnConfig' of null
Any help would greatly appreciated
Edit:
Views component
const Views = forwardRef(({ user, id }, ref) => {
useEffect(() => {
handleOnConfig();
}, []);
return (
<div>
<Component
user={user}
id={id}
name='Component'
/>
</div>
);
})
export default Views;
Not a problem with spyOn() directly: your view variable is null.
Try using .dive() in the return from shadow():
beforeEach(() => {
let props = {user:user}
view = shallow(<Views {...props} />).dive().instance(); // <-- added .dive()
});
I'm trying to use React context to decide whether to have a button or not, and the problem is my context always runs twice and returns the first value as undefined -- the second time the output is correct.
Context:
const defaultMyContextValue = null;
export const myContext = createContext<GenericResponseFromEndpoint | null>(
defaultMyContextValue
);
export const fetcher = async (
endpoint: 'an_endpoint',
id: string
) => {
const client = new Client().ns('abcdef');
try {
return await client.rpc(
endpoint,
{
id
},
{}
);
} catch (err) {
// log error
return undefined;
}
};
export const MyContextProvider: React.FC = ({children}) => {
const context = useAnotherContext();
const {id} = useMatch();
const fetchMyContext = useCallback(
(endpoint: 'an_endppoint', id: string) =>
fetcher(endpoint, id),
[id]
);
const {data = null} = useSWR(
context?.name && ['an_endpoint', id],
fetchMyContext
);
return <myContext.Provider value={data}>{children}</myContext.Provider>;
};
export const useMyContext = () => {
const context = useContext(myContext);
if (context === undefined) {
throw new Error('------------------------');
}
return context;
};
Conditional render:
export const contextElement: React.FC = () => {
const info = useMYContext()?.info;
if (!info) {
return null;
// console.log('null');
}
console.log('not null');
// when i run it, it always returns two output scenarios:
// undefined - undefined
// undefine - expected value
// the front-end works as expected
return (
<div className="some-class-name">
<Button
variant="primary"
data-testid="button-123"
onClick={() => window.open('_blank')}
>'Do Something',
})}
</Button>
</div>
);
};
Test: my tests failed and the error is the system couldn't find the element. If I set the style={display:none} instead of returning null in the above conditional rendering -- it passes
describe('contextElement', () => {
const renderSomething = () => render(<contextElement />);
afterEach(() => {
myMock.mockClear();
});
it('renders button', () => {
myMock.mockResolvedValue({
info: 'some info'
});
const {getByTestId} = renderSomething();
expect(getByTestId('button-123')).toBeTruthy();
});
it('does not render button', () => {
myMock.mockResolvedValue(undefined);
const {getByTestId} = renderSomething();
expect(getByTestId('button-123')).not.toBeTruthy();
});
});
It's a really long post I know. Thanks for making it till the end. And yes, I check and there's no strictMode in my set-up. Thank you.
enter image description here
Find the attached image
I am getting this following error, while running Unit test for my react file.
I couldn't able to set value for a state method.
TestFile.tsx
const [attr, setAttributes] = useState<any>(initialState);
const getDetail = async () => {
if (Id) {
const form: IForm = await getResponse(Id);
console.log("||" + form.attributes.sourceName)
setFormResponseAttributes(form.attributes);
console.log("***" + JSON.stringify(attr));
};
useEffect(() => {
getDetail();
}, []);
return(
{attr.sourceName === 'ECR' ?
<div className='fe_u_padding--right-medium'>
<Button
id='saveDraftButtonId'
text='Save as Draft'
onClick={() => saveForm(true)}
variant='secondary'
className='hide-while-printing'
/>
</div>
: null
);
}
export
TestFile.test.tsx
it('load form response', () => {
const getResponseSpy = jest.spyOn(ResponseApi, 'getResponse');
getResponseSpy.mockImplementation(() => Promise.resolve(testUtils.Response));
const setAppContextSpy = jest.fn();
let setResponseAttributes;
const wrapper = mount(
<BrowserRouter>
<RegisteredApplicationContext.Provider
value={{ appContext: testUtils.registeredApplication, setAppContext: setAppContextSpy }}
>
<FormResponse match={{ params: { formResponseId: 'formResponseId1' } }} />
</RegisteredApplicationContext.Provider>
</BrowserRouter>
);
wrapper.find(Button).find('#saveDraftButtonId').first().simulate('click', {});
wrapper.update();
expect(getFormResponseSpy).toBeCalled();
TestUtils
export const Response: IForm = {
id: uuidv4(),
attributes: {"contextId": "111","sourceName" : "ECR"}
}
I am getting error while reading the SaveDraftButtonId,
Method “simulate” is meant to be run on 1 node. 0 found instead.,
it could able to find that button coz it couldn't set the value for attr state value
Any inputs would be helpful
TIA
I am using Chakra UI and I have to mock just one hook, because I want to simulate various viewports.
My component is using the hook as following:
export const AuthenticationBase = (props: props) => {
const [isMobile] = useMediaQuery(['(max-width: 768px)']);
return (
<Box textAlign="center" fontSize={isMobile ? 'sm' : 'xl'}>
</Box>
);
}
I tried as following:
// runs before any tests start running
jest.mock("#chakra-ui/react", () => {
// --> Original module
const originalModule = jest.requireActual("#chakra-ui/react");
return {
__esModule: true,
...originalModule,
useMediaQuery: jest.fn().mockImplementation(() => [true]),
};
});
And then I execute my test:
describe('Authentication Component', () => {
it('should load with Login', () => {
const container = mount(<ChakraProvider theme={theme}><AuthenticationBase screen="login" /></ChakraProvider>);
const title = container.find('h1');
expect(title).toBeTruthy();
expect(title.text()).toBe('Login');
container.unmount();
});
}
But I get an error from JEST, somehow the hook is not mock correctly:
I am learning to test React app using jest and Enzyme . I have created a component and using redux to maintain and update the state . The component code is below .
Now i want to write the test to check initial value of prodOverviewAccordion which we are setting as true in context file.
I have tried writing , but getting error . Sharing the test code also . Please help
const ProdOverview = () => {
const {
productState,
setProdOverviewAccordion
} = React.useContext(ProductContext);
const {prodOverviewAccordion } = productState;
const [completeStatusprod, setCompleteStatusprod] = useState(false);
return (
<div onClick={toggleTriggerProd}>
<s-box>
<Collapsible
trigger={
<Accordion
name={ProductConfig.accordionTriggerLabels.prodOverviewLabel}
completeStatusIcon={completeStatusprod ? 'check-circle' : 'alert-triangle'}
completeStatus={completeStatusprod}
/>
}
easing='ease-out'
handleTriggerClick={() => {
if (!prodOverviewAccordion) {
setProdOverviewAccordion(true);
} else {
setProdOverviewAccordion(false);
}
}}
open={prodOverviewAccordion}
data-test='prodOverViewCollapsible'
>
<p>Test</p>
</Collapsible>
</s-box>
</div>
);
};
export default ProdOverview;
const prodsetup = (props = {}) => {
return shallow(<ProdOverview />);
};
describe('Product Overview panel Test', () => {
const mockSetCurrentGuess = jest.fn();
beforeEach(() => {
mockSetCurrentGuess.mockClear();
});
test('should render Collapsible panel', () => {
const wrapper = prodsetup();
const component = findByTestAttr(wrapper, 'prodOverViewCollapsible');
expect(component.length).toBe(1);
});
test('Product Overview Panel should be in open state', () => {
const wrapper = prodsetup();
expect(wrapper.state().prodOverviewAccordion.to.equal(true));
});
});