如何用 Jest 测试 CSS Font Loading API(介绍)

2024/10/25 0:03:13

本文主要是介绍如何用 Jest 测试 CSS Font Loading API(介绍),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

模拟和验证字体加载流程:在Jest中的应用

图片来源:canopas

激动人心的消息!我们的博客有了一个新的新家!🚀

介绍

假设你想要将动态字体添加到你的网站。这里所说的动态字体指的是,它们应该根据条件加载,或者可以通过 API 响应获取。你不能直接通过 @font-face CSS 选择器来添加它们。

因此,在这种情形下,CSS Font Loading API 会很有用,使用 FontFace 加载和管理你的网页应用中的自定义字体。

在这篇博客文章中,我们将探讨如何在 typescript 中加载自定义字体以及编写Jest测试,以测试这些操作。

赞助

告别不切实际的幻想,开始有实际的愿望,从Justly开始,让你的愿望更加实际。

Justly: 习惯、目标、日记 建立一个让自己每天进步1%的计划。justly.life
使用字体加载API来加载自定义字体文件

字体有两个主要属性,字体家族(例如 Roboto)和 样式(例如 Bold 或 Light)以及相关的文件。如下可能就是字体的结构,

字体类型定义如下:
Font 类型: {
  family: 字体族;  
  style: 样式;  
  file: 文件;
} 等

假设你有一个如下所示的 fonts 数组

    const 字体数组: 字体[] = [  
      {  
        字体族: 'Roboto',  
        样式: '常规',  
        文件: 'Roboto-Regular.ttf',  
      },  
      {  
        字体族: 'Roboto',  
        样式: '粗体',  
        文件: 'Roboto-Bold.ttf',  
      },  
    ]

在处理字体时,有用的实体元素,

  • FontFace 构造函数:用于在网页应用中初始化字体,相当于 @font-face。
  • FontFaceSet 管理字体加载并查询下载进度。
  • document.font: 浏览器中已加载的字体集合

我们可以这么用它们,

    export const loadFonts = async (fonts: Font[]): Promise<FontFaceSet> => {  

      // 获取已加载的字体,避免重复加载  
      const existingFonts = new Set(  
        Array.from(document.fonts.values()).map(  
          (fontFace) => fontFace.family  
        )  
      );  

      // 将待加载的字体加入文档  
      fonts.forEach((font) => {  
        const name = `${font.family}-${font.style}`;  

        // 如果字体已存在,则返回  
        if (existingFonts.has(name)) return;  

        // 初始化字体  
        const fontFace = new FontFace(name, `url(${font.file})`);  
        document.fonts.add(fontFace);  // 准备字体集合  
      });  

      // 返回字体集合的 Promise  
      return document.fonts.ready.then();  
    }

当文档中的字体加载完成后,FontFaceSet 的承诺将得到完成,不再需要进一步加载字体。

就这样

这是加载自定义字体最简单的方式。

字体测试

虽然通过API管理字体资源非常简单,但是确保通过测试确保字体的正确运行至关重要,因为在进行测试时,由于没有浏览器环境,这可能会导致错误。

让我们尝试写一个不使用浏览器模拟环境的单元 Jest 测试,

    describe('loadFonts', () => {  
      it('不应该重复添加已经在文档中存在的字体', async () => {  
         await utils.loadFonts(fonts);  
         expect(document.fonts.add).not.toHaveBeenCalled();  
      });  

      it('应该加载新字体到文档中', async () => {  
         document.fonts.values = jest.fn(() => [] as any);  
         await utils.loadFonts(fonts);  
         expect(document.fonts.add).toHaveBeenCalled();  
       });  
    });

它出现了这样的错误。这里的 undefined 指的是 document.fonts。

TypeError: 无法读取 'values' 属性,因为它是 undefined

让我们模拟一下 document.fonts,因为在 jest 环境下用不到它们。先创建一个 FontFaceSet 对象,并给它添加需要的属性。

    // 模拟的FontFaceSet 对象  
     const mockFontFaceSet = {  
       add: jest.fn(),   // 用于向document.fonts 添加字体  
       ready: Promise.resolve(), // 用于管理字体的加载  
       values: jest.fn(() => [ // 返回现有的字体信息  
         { family: 'Roboto-Regular' },  
         { family: 'Roboto-Bold' }  
       ])  
     };

然后定义一下 document.fonts 对象(或简称 document.fonts)。

    Object.defineProperty(document, 'font', {  
        value: mockFontFaceSet,  
    });

现在,当运行测试时,当遇到 document.fonts 时,jest 将将其用作 document.fonts,返回 mockFontFaceSet

重新写一下这些测试。

    describe('加载字体', () => {  
       it('不应该向已经包含这些字体的文档中添加字体', async () => {  
         await utils.loadFonts(fonts);  
         expect(document.fonts.add).not.toHaveBeenCalled(); // 验证没有调用 add 方法
       });  

       it('应该将新字体加载到文档中', async () => {  
         document.fonts.values = jest.fn(() => [] as any);  
         await utils.loadFonts(fonts);  
         expect(document.fonts.add).toHaveBeenCalled(); // 验证调用了 add 方法
       });  
     });

我们将为第二个测试用例收到错误 ReferenceError: FontFace is not defined,这是因为 FontFace 在没有浏览器的情况下也是不可用的。

这里是在 jest.setup.ts 文件中定义字体的方法。

    (global as any).FontFace = class {  
      constructor(public family?: string, public source?: string) { }  
    };

这样一来,现在fontface可以在jest测试环境中使用,并且具有与fontface构造函数相同的字体加载API的功能。

这篇博客文章最初发表在canopas.com

若要阅读完整版本,请访问该博客这里

结语

浏览器环境在服务器测试环境中不可用,因此我们需创建一个浏览器实例的复制,以保证顺利运行。

开个玩笑来说,我们可以定义自定义变量并模拟浏览器环境。你可以使用相同的方法,比如模拟其他浏览器特性,比如 locationnavigator

就这样,今天的分享到此为止。继续探索,更多惊喜等你发现!!

相关文章
Vue 3 组件测试与 Jest 前端 Vue 组件测试canopas.com
使用Gin和MySQL进行测试驱动开发(TDD)的Go语言之旅

开启Go语言测试之旅

感谢有你和我们一起经历这段旅程!

作为作者,如果你喜欢你所读的内容,一定要点个赞&#128079;&#128079;&#128079;,这对我来说意义非凡!

请在下方的评论区里留下您的想法。您的意见让我们的内容更加丰富,激励我们为您带来更多有价值和有信息量的文章。

关注Canopas以了解有趣文章的更新!



这篇关于如何用 Jest 测试 CSS Font Loading API(介绍)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程