我需要澄清一下,按照单元测试的标准,这些测试中的哪一个是100%的单元测试



我有两段测试API端点的代码,我知道单元测试不会向服务器发出HTTP请求,因为我正在用伪数据构建API服务(只使用数组和其他数据结构来保存数据)。我想知道其中哪一个是真正的单元测试(根据单元测试的真正定义)

我读过很多关于TDD和BDD的教程,我知道代码的第一个版本是验收测试,我的问题是,在许多教程中,这个第一个版本被称为单元测试,但有些人说它是验收测试。我有点困惑

// first version -- the one I believe to be acceptance test
it('should return a list of meetups that meets the search criteria', (done) => {
agent
.get('/api/v1/meetups/search')
.query({ searchTerm: 'meetup 1' })
.expect(200)
.end((err, res) => {
if (err) return done(err);
res.body.status.should.equal(200);
res.body.data.should.be.an('array');
res.body.data.length.should.be.greaterThan(0);
done();
});
});
// second version -- using sinon to mock req and res object used in the route handler function
it('can search for meetups by topic', () => {
const req = {
query: {
searchTerm: 'Sample Meetup'
}
};
const res = {
status() { },
send() { }
};
res.status = sinon.stub(res, 'status').returns(res);
res.send = sinon.stub(res, 'send').returns(res);
myController.searchMeetups(req, res);
res.status.firstCall.args[0].should.equal(200);
res.send.firstCall.args[0].should.have.property('data');
res.send.firstCall.args[0].data.length.should.be.greaterThan(0);
});

测试工作,对于这两个版本,我想澄清API验收测试,如果它是API 的一个合适的单元测试

意见ahoy:

第二种方法绝对是单元测试。

第一种方法更接近于验收测试,尽管我更喜欢称之为功能性测试。据推测,任何后端数据库等仍然是模拟出来的。

您没有问的问题是,哪种方法更适合测试REST API?在我看来,明确的答案是第一种方法。这为您提供了一系列尽可能模仿实际API用户体验的测试,它允许您对每个测试的响应和返回的头值等做出清晰简洁的陈述

为您的单个模型方法保留单元测试,为您的控制器方法进行功能测试。那是我的0.02美元。

欢迎来到SO!

你在这里所做的确实是一次验收测试。它也可能符合集成测试的条件。

在这个测试中,你正在测试(胡乱猜测-我不知道你的服务到底做了什么,但希望你能明白):

  • 服务器正确运行的事实
  • 可能是一个或多个身份验证方法,用于验证用户是否拥有请求此URI的所有必要权限
  • 可能还有很多其他中间件的东西,正确地准备您的请求,格式化您的数据等等
  • 也许有几个数据库来回
  • 可能是一些用于日志记录、调试等的工具
  • 服务的核心功能(以正确的格式返回聚会列表)

这对于一个测试来说是很多东西!如果管理这一切的数百行代码中只有一行(有些是你写的,有些是其他人写的)有一个错误,那么很多事情都会出错。最后,你唯一关心的是一个包含几个项的数组,这是用户期望的功能,即accepts。这就是为什么我们称之为UAT(或用户接受测试)。

您也可以说这是一个integration测试,因为您正在测试应用程序的单独部分:服务器和数据库。

您还可以了解E2E(端到端)测试:例如,这将测试前端是否也正确显示它从刚刚测试的后端检索到的所有会议。还有许多其他类型的测试。。。

单元测试真正测试的是你能找到的最小的可测试代码单元。在您的场景中,在您的请求的生命周期中有大量的函数。给定参数X,函数Y是否总是返回Z?函数A、B、C、D…怎么样。。。?

换言之:如果你上面的测试失败了,你知道你的代码的哪一部分失败了吗?如果你的代码中有两个问题,但由于请求在第一个错误时失败了,你怎么知道呢?还有:你如何才能确保这一部分永远不会再次失败?

编写测试有点乏味,有很多方法可以做到这一点。有时,在没有任何其他依赖性的情况下测试一个函数是不可能的(或非常困难的)(例如,调用数据库的函数),并且不能指望你100%测试一个非常非常大的项目。但你应该瞄准一个"足够大"的数字。

有时,一个问题是单元测试代码之间的"粘合剂"。网络问题可能发生在完美的功能之间,或比赛条件之间,或。。。在这种情况下,您需要进行集成测试。

最新更新