使用Solid原理在Node.js中进行示例测试

2020-06-10 06:30:06

根据一些业务逻辑,您需要定期向某些用户发送电子邮件(例如,时事通讯)。

以MongoDB为例,当然持久性可以根据您的喜好进行更改。

为您的内部模块和功能制定明确的合作者和职责是很重要的。

如果您通过使用TDD测试驱动应用程序来启动应用程序,这几乎是免费的。

TEST(向尚未收到新闻稿的用户发送新闻稿';,异步t=>;{等待UserRepository.insert({name:';test';,email:';[电子邮件受保护]';,lastEmailSentAt:null})等待新闻稿。run()//我应该在此声明什么?//我们需要新闻稿的协作者.})。

为了定义合作者,我尝试遵循单一责任原则(来自可靠原则家族)。

您可以更进一步,从业务角度来看待它:

谁是与特定软件组件或模块相关联的";角色(如个人或业务部门)?

它断言在调用findNotYetReceivedNewsletter方法时,返回了正确的用户数。

测试(';查找尚未收到时事通讯的用户';,异步t=>;{等待UsersCollection.insert({name:';test';,email:';[电子邮件受保护]';,lastEmailSentAt:New Date()})等待UsersCollection.insert({name:';test';,email:';[电子邮件受保护。)const Users=await userRepository.findNotYetReceivedNewsletter()t.true(Array.isArray(Users))t.is(users.length,1)t.true(UsersCollection.find.calledOnce)t.true(UsersCollection.find.calledWith({lastEmailSentAt:null}))})。

在这种情况下,电子邮件的实际发送是已清除的,因此不会实际发送任何电子邮件。

test(将时事通讯发送给用户';,异步t=>;{const user={name:';test';,email:';[电子邮件受保护]';,lastEmailSentAt:null}const emailStub=sinon.stub(email,';send';)等待emailService.sendTo(User)t.is(emailStub.callCount,

人们可能倾向于将所有逻辑放在一个函数中,然后就到此为止。

它可能会奏效,但能持续多久呢?或者更好的是:如何有效地测试它?

在第一个UAT中,我认为很明显,我们需要提供时事通讯模块,至少提供一种方法来检索用户。

让我们在UserRepository中尝试一下,并断言已查询Users集合以查找尚未收到时事通讯的用户:

test(';向尚未收到的用户发送时事通讯';,异步t=>;{等待db.get(';用户';).insert({name:';test';,email:';[电子邮件受保护]';,lastEmailSentAt:null})sinon.spy(userRepository,';findNotYetReceivedNewsLetter&)。)等待时事通讯。运行(用户存储库)t.is(userRepository.findNotYetReceivedNewsletter.callCount,1)//我们仍需要协作者来发送时事通讯.})。

使用.spy,因为我希望查询数据库,并在稍后断言函数已被调用。

对于电子邮件,我不希望调用真正的函数,因此使用.stub。

我在测试中传入了合作者,并在应用程序代码中使用真正的实现。

异步函数运行(userRepository,emailService){const Users=await userRepository.findNotYetReceivedNewster()for(用户的const用户){await emailService.sendTo(User)}}。

test(';向尚未收到的用户发送时事通讯';,异步t=>;{等待db.get(';用户';).insert({name:';test';,email:';[电子邮件受保护]';,lastEmailSentAt:null})sinon.spy(userRepository,';findNotYetReceivedNewsLetter&)。)等待时事通讯.run(userRepository,emailService)t.is(userRepository.findNotYetReceivedNewsletter.callCount,1)t.is(emailService.sendTo.callCount,1)//实现您关于参数的断言,如电子邮件的";收件人";,";主题";,";内容等})。

├──index.js├──index.test.js├──lib│├──db.js│├──Email-Service.js│├──Email-Service.test.js│├──email.js│├──email.test.js│├──User-Repository.js│└──User-Repository.test.js├──Package.lock.json└──Package.json。

其他软件组件都经过了单元测试,有关更多详细信息,请查看GitHub上的项目

每个合作者都有自己的测试(除了lib/db.js,因为它是一个围绕monk的简单包装器,已经经过了很好的测试)。

js是选择用来发送电子邮件的API的包装器,并且有一个公开的函数.Send。