在 Mocha 测试中如何使用 Test Doubles 进行 Mocking 和 Stubbing?

在前端开发中,测试是一个必不可少的环节。Mocha 是一个强大的 JavaScript 测试框架,可以用于测试前端应用的各种功能和组件。在 Mocha 的测试中,有时候需要使用 Test Doubles 来进行 Mocking 和 Stubbing。这篇文章将介绍 Test Doubles 的概念、如何在 Mocha 测试中使用他们,并且提供一些示例代码来帮助你更好地理解。

什么是 Test Doubles?

Test Doubles 是一种测试编程技术,用于在单元测试中替代被测试代码的一些组件或行为,以便更好地控制测试条件。它是一个广泛的概念,包括 Mocking、Stubbing、Spying 等技术。

在 Mocking 和 Stubbing 中,Test Doubles 是一个替代的组件,它有着和原来组件相同的 API,但并不真正执行任何操作,而是为测试提供了一个被控制的环境。在 Spy 中,Test Doubles 同样是一个替代组件,不过它会记录原来组件的行为,以便测试后进行分析。

Mocking 和 Stubbing

大多数情况下,Mocking 和 Stubbing 用于模拟某些操作或直接模拟函数。Mocking 通常用于创建完全捏造的组件,而 Stubbing 用于修改组件的特定行为,以便测试它不同的用例。

在 Mocha 测试中,Mocking 和 Stubbing 可以通过一些库完成。下面我们将会介绍两种常用的库:sinon 和 testdouble.js。

使用 sinon

sinon 是一个用于 JavaScript 测试的独立库,可以用于实现 Mocking、Stubbing 和 Spy。Sinon 可以轻松地创建一个假的对象或者钩子。

Mocking

Mocking 可以用于创建一个假的对象,这个假对象可以代替一个真实对象,并且可以模拟与真实对象相同的行为。

// 假设有一个模块模拟了 Ajax 请求
const Ajax = {
  get: function(url, callback) {
    // 执行 Ajax 请求,并在得到数据后调用回调函数
  }
};

假设这个模块已经被测试过多次,现在需要为这个模块创建一个 Mock 对象,并且在测试中使用它:

// 创建一个 Mock
const AjaxMock = {
  get: function(url, callback) {
    // 在测试中,我们不希望这个函数真的请求服务器,因此我们会以一个假数据代替
    const fakeData = {
      success: true
    };
    callback(fakeData);
  }
};

// 用 Mock 替换原来的模块
sinon.replace(Ajax, 'get', AjaxMock.get);

// 执行测试
it('should return success', function(done) {
  // 执行模块
  Ajax.get('http://example.com', function(result) {
    // 检查返回结果是否是假数据
    assert.equal(result.success, true);
    done();
  });
});

// 恢复被替换的函数
sinon.restore();

Stubbing

Stubbing 可以用于修改一个真实对象的行为,例如它的返回值或者它的函数执行的次数等。

// 假设有一个模块模拟了 Ajax 请求
const Ajax = {
  get: function(url, callback) {
    // 执行 Ajax 请求,并在得到数据后调用回调函数
    callback('some data');
  }
};

现在,需要对这个模块进行 Stubbing,随后使用它进行测试:

// Stub get 方法的行为
sinon.stub(Ajax, 'get').callsFake(function(url, callback) {
  callback('fake data');
});

// 执行测试
it('should return fake data', function(done) {
  // 执行模块
  Ajax.get('http://example.com', function(result) {
    // 检查是否返回了假数据
    assert.equal(result, 'fake data');
    done();
  });
});

// 恢复被替换的函数
Ajax.get.restore();

使用 testdouble.js

testdouble.js 是一个轻量级测试框架,可以用于创建 Mocks 和 Stubs,非常易于使用。

Mocking

Mocking 可以用于创建一个假的对象,这个假对象可以代替一个真实对象,并且可以模拟与真实对象相同的行为。

// 假设有一个模块模拟了 Ajax 请求
const Ajax = {
  get: function(url, callback) {
    // 执行 Ajax 请求,并在得到数据后调用回调函数
  }
};

假设这个模块已经被测试过多次,现在需要为这个模块创建一个 Mock 对象,并且在测试中使用它:

// 创建一个 Mock
const AjaxMock = td.object(Ajax);

// 用 Mock 替换原来的模块
td.replace(Ajax, 'get', AjaxMock.get);

// 设置 Mock 的行为
td.when(AjaxMock.get('http://example.com')).thenCallback({ success: true });

// 执行测试
it('should return success', function(done) {
  // 执行模块
  Ajax.get('http://example.com', function(result) {
    // 检查返回结果是否是假数据
    assert.equal(result.success, true);
    done();
  });
});

// 恢复被替换的函数
td.reset();

Stubbing

Stubbing 可以用于修改一个真实对象的行为,例如它的返回值或者它的函数执行的次数等。

// 假设有一个模块模拟了 Ajax 请求
const Ajax = {
  get: function(url, callback) {
    // 执行 Ajax 请求,并在得到数据后调用回调函数
    callback('some data');
  }
};

现在,需要对这个模块进行 Stubbing,并使用它进行测试:

// Stub get 方法的行为
td.when(Ajax.get('http://example.com')).thenCallback('fake data');

// 执行测试
it('should return fake data', function(done) {
  // 执行模块
  Ajax.get('http://example.com', function(result) {
    // 检查是否返回了假数据
    assert.equal(result, 'fake data');
    done();
  });
});

// 恢复被替换的函数
td.reset();

总结

在本文中,我们介绍了 Test Doubles 的概念、Mocking 和 Stubbing 两种技术,以及如何在 Mocha 测试中使用它们。我们通过示例代码演示了如何使用 sinon 和 testdouble.js 这两个工具库来实现 Mocking 和 Stubbing。在实际开发中,采用哪种库取决于个人喜好,应该选择最适合你的工具来完成工作。Test Doubles 技术的学习对于提高测试可以帮助工程师创建测试环境,对于最终代码的调整和最终结果的优化以及开发流程的效率都是有极大帮助的。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a4db87add4f0e0ffd34fee


纠错反馈