测试驱动的开发
如果您是TDD或Jest的新手,请查看本文末尾的资源部分。
代码
我有一个反应组件,SiteBreadcrumbs.tsx
,它使用BreadcrumbsHelper
类生成站点面包屑。
sitebreadcrumbs.tsx
import BreadcrumbsHelper from '../../../../utils/BreadcrumbsHelper';
import { BreadcrumbDataProvider } from '../../../../dal/BreadcrumbDataProvider';
import { PageContextDataProvider } from '../../../../dal/PageContextDataProvider';
React.useEffect(() => {
//...
const helper = new BreadcrumbsHelper(dataProvider, pageContextProvider);
helper.getBreadcrumbs()
.then((result) => {
setLinkItems(result);
})
.catch((error) => {
console.log(error);
});
}, []);
breadcrumbshelper.ts
export default class BreadcrumbsHelper {
constructor(protected dataProvider: BreadcrumbDataProvider, protected pageContextProvider: PageContextDataProvider) {}
public getBreadcrumbs = async (): Promise<IBreadcrumbItem[]> => {
const items: IBreadcrumbItem[] = [];
//...
return items;
}
//...
}
测试
不是很好的方法
jest允许mocking partials,因此我可以使用以下代码模拟BreadcrumbsHelper.getBreadcrumbs()
方法:
sitebreadcrumbs.test.tsx
jest.mock('../../src/utils/BreadcrumbsHelper', () => {
const originalModule = jest.requireActual('../../src/utils/BreadcrumbsHelper');
return {
__esModule: true, //<- required for ES modules
...originalModule,
default: jest.fn().mockImplementation(() => {
return {
getBreadcrumbs: jest.fn().mockImplementation(() => {
return Promise.resolve([];
})
};
}),
};
});
但是,在我的测试中,我想介绍不同的情况:网站的欢迎页面,网站(其他)页面,subsite等。我当然不会创建单独的文件来覆盖它们。
正确的方法
您会发现许多有关如何模拟功能的示例,但是这里复杂的部分是getBreadcrumbs
是一种类方法,并且不作为函数导出。
jest要求jest.mock('../../src/utils/BreadcrumbsHelper')
在测试之上,但是我可以使用每个测试更改getBreadcrumbs
模拟。
(BreadcrumbsHelper as jest.Mock).mockReturnValueOnce({
getBreadcrumbs: jest.fn().mockResolvedValue(BreadcrumbsConfig.TeamSiteWelcomePage)
})
sitebreadcrumbs.test.tsx
import BreadcrumbsHelper from '../../src/utils/BreadcrumbsHelper';
jest.mock('../../src/utils/BreadcrumbsHelper')
const BreadcrumbsConfig = {
TeamSiteWelcomePage: [
{ "text": "Intranet", "key": "1", "href": "https://contoso.sharepoint.com/sites/Intranet"}
],
TeamSiteInsightsPage: [
{ "text": "Intranet", "key": "1", "href": "https://contoso.sharepoint.com/sites/Intranet"},
{ "text": "Insights", "key": "2", "href": ""}
],
//...
}
describe('SiteBreadcrumbs', () => {
it('should render breadcrumbs on TeamSite WelcomePage', async () => {
(BreadcrumbsHelper as jest.Mock).mockReturnValueOnce({
getBreadcrumbs: jest.fn().mockResolvedValue(BreadcrumbsConfig.TeamSiteWelcomePage)
})
await act(async () => {
siteBreadcrumbs = render(<SiteBreadcrumbs pageContext={mockPageContext} spfiContext={mockSPFI} />);
});
//...
});
it('should render breadcrumbs on TeamSite InsightsPage', async () => {
(BreadcrumbsHelper as jest.Mock).mockReturnValueOnce({
getBreadcrumbs: jest.fn().mockResolvedValue(BreadcrumbsConfig.TeamSiteInsightsPage)
})
await act(async () => {
siteBreadcrumbs = render(<SiteBreadcrumbs pageContext={mockPageContext} spfiContext={mockSPFI} />);
});
//...
});
}