React中如何用Enzyme和Jest测试onSortedChange方法的分支逻辑?
onSortedChange Method with Jest and Enzyme Let's break down how to fix your test coverage gaps and properly validate every branch in your onSortedChange method. First, let's spot the key issues in your current test:
- You're passing a string
'test'toonSortedChange, but the method expects an array containing an object withidanddescproperties (since you referenceobj[0].idandobj[0].descin the code). - Your current test doesn't validate the actual state changes or branch-specific logic, which is why you're missing coverage for the switch cases and default branch.
Step 1: Mock the searchUnsubscribed Method
Since your method calls this.searchUnsubscribed() after setting state, you should mock this method to verify it's triggered correctly (and avoid any side effects from the real implementation).
Step 2: Write Test Cases for Every Branch
You need to test three core scenarios, plus their ascending/descending variations to cover all code paths:
Test 1: AccountName Case (Ascending & Descending)
Verifies the expand state gets the correct $orderby clause tied to ACCOUNT/AccountName.
Test 2: SecurityName Case (Ascending & Descending)
Similar to the above, but validates logic for SECURITY/SecurityName.
Test 3: Default Case (Any Other ID)
Covers the missing default branch, where tempBaseOrderby is set instead of modifying temp.
Full Test Code Example
import { mount } from 'enzyme'; import Unsubscribe from './Unsubscribe'; // Adjust import path to match your component describe('Unsubscribe Component - onSortedChange', () => { let wrapper; let searchSpy; beforeEach(() => { // Mount the component and mock the search method before each test wrapper = mount(<Unsubscribe />); searchSpy = jest.spyOn(wrapper.instance(), 'searchUnsubscribed'); // Clear mock call history to avoid cross-test contamination searchSpy.mockClear(); }); afterAll(() => { // Restore the original method after all tests complete searchSpy.mockRestore(); }); it('should handle AccountName sort (ascending)', () => { const sortObj = [{ id: 'AccountName', desc: false }]; wrapper.instance().onSortedChange(sortObj); // Validate state updates expect(wrapper.state('expand')).toBe('&$expand=SECURITY,POLICY1,ACCOUNT&$orderby=ACCOUNT/AccountName'); expect(wrapper.state('orderby')).toBe(''); // Confirm search method was triggered expect(searchSpy).toHaveBeenCalled(); }); it('should handle AccountName sort (descending)', () => { const sortObj = [{ id: 'AccountName', desc: true }]; wrapper.instance().onSortedChange(sortObj); expect(wrapper.state('expand')).toBe('&$expand=SECURITY,POLICY1,ACCOUNT&$orderby=ACCOUNT/AccountName desc'); expect(wrapper.state('orderby')).toBe(''); expect(searchSpy).toHaveBeenCalled(); }); it('should handle SecurityName sort (ascending)', () => { const sortObj = [{ id: 'SecurityName', desc: false }]; wrapper.instance().onSortedChange(sortObj); expect(wrapper.state('expand')).toBe('&$expand=SECURITY,POLICY1,ACCOUNT&$orderby=SECURITY/SecurityName'); expect(wrapper.state('orderby')).toBe(''); expect(searchSpy).toHaveBeenCalled(); }); it('should handle SecurityName sort (descending)', () => { const sortObj = [{ id: 'SecurityName', desc: true }]; wrapper.instance().onSortedChange(sortObj); expect(wrapper.state('expand')).toBe('&$expand=SECURITY,POLICY1,ACCOUNT&$orderby=SECURITY/SecurityName desc'); expect(wrapper.state('orderby')).toBe(''); expect(searchSpy).toHaveBeenCalled(); }); it('should handle default case sort (ascending)', () => { const sortObj = [{ id: 'CreatedDate', desc: false }]; // Use any ID not in switch cases wrapper.instance().onSortedChange(sortObj); expect(wrapper.state('expand')).toBe('&$expand=SECURITY,POLICY1,ACCOUNT'); expect(wrapper.state('orderby')).toBe('&$orderby=CreatedDate'); expect(searchSpy).toHaveBeenCalled(); }); it('should handle default case sort (descending)', () => { const sortObj = [{ id: 'CreatedDate', desc: true }]; wrapper.instance().onSortedChange(sortObj); expect(wrapper.state('expand')).toBe('&$expand=SECURITY,POLICY1,ACCOUNT'); expect(wrapper.state('orderby')).toBe('&$orderby=CreatedDate desc'); expect(searchSpy).toHaveBeenCalled(); }); });
Key Notes:
- We use
beforeEachto set up a clean component instance and mock for every test, ensuring no cross-test interference. - Each test targets a specific branch and sort direction, making it easy to debug if any case fails.
- We validate both
expandandorderbystate values to ensure they match the expected string for each scenario. - The mock for
searchUnsubscribedlets us confirm the method runs after state is updated, without executing the real search logic.
Running these tests should give you 100% code coverage for the onSortedChange method.
内容的提问来源于stack exchange,提问作者usertestREACT

