简体   繁体   English

单元测试restful webservices

[英]unit testing restful webservices

I am wondering if anyone knows the proper way to unit test a restful webservice. 我想知道是否有人知道单元测试一个宁静的Web服务的正确方法。 I have a set of webservices built using recess, and I would like to write test code for them. 我有一组使用凹槽构建的web服务,我想为它们编写测试代码。 Unfortunately, since my webservices are tied to a database, my tests end up populating the database which seems like a problem. 不幸的是,由于我的webservices绑定到数据库,我的测试最终会填充数据库,这似乎是一个问题。

I am mostly asking about the proper approach to dealing with this from a unit test standpoint. 我主要是从单元测试的角度询问处理这个问题的正确方法。 Do I clear the database of the values I have inserted after testing? 我是否在测试后清除了我插入的值的数据库? Do I have a special test database with a whole set of special test routes? 我是否有一套带有一整套特殊测试路线的特殊测试数据库? I am at a bit of a loss for the best way to approach this. 对于解决这个问题的最佳方法,我感到有点失落。

Obviously in other cases of similar database wrapper classes you would just pass in a dummy database that you set up at the beginning of the tests. 显然,在类似数据库包装类的其他情况下,您只需传入在测试开始时设置的虚拟数据库。 This seems like it would be much more challenging though when it comes to working with a restful framework like recess. 这似乎更具挑战性,尽管它涉及到像休息这样的宁静框架。

I'd appreciate any thought you all might have on the right way to deal with tests saving information to the database. 我很感激你们所有人都可能以正确的方式处理将信息保存到数据库的测试。

Thanks in advance. 提前致谢。

Generally when testing a web service you are testing the full stack, from the outside in. This means you request a resource and check if the results conform to your expectations. 通常,在测试Web服务时,您要从外部测试完整堆栈。这意味着您请求资源并检查结果是否符合您的期望。

In nearly all cases populating the database right before every request is a good approach. 几乎在所有情况下,在每个请求之前填充数据库都是一个好方法。 It might seem like overkill, but in reality with a web service you can't guarantee proper test coverage by mocking/stubbing various elements. 这似乎有点矫枉过正,但实际上通过Web服务,您无法通过模拟/存储各种元素来保证正确的测试覆盖率。

Coming from the Ruby world, Cucumber is the ideal approach as it lets you test from a high level. 来自Ruby世界, Cucumber是理想的方法,因为它可以让您从高级别进行测试。 When you combine this with Rspec to do actual unit testing (lower level tests that query your objects directly) you get the best of both worlds. 当你将它与Rspec结合起来进行实际的单元测试(直接查询对象的低级测试)时,你将获得两全其美的效果。 These libraries even come with something called 'database cleaner' which will manage populating and depopulating the database for you. 这些库甚至带有一个名为“数据库清理器”的东西,它将管理为您填充和减少数据库的数量。

You might find the following blog post by Rspec's author very helpful, as it explains brilliantly why you should avoid too much mocking and stubbing. 您可能会发现Rspec的作者对以下博客文章非常有帮助,因为它精辟地解释了为什么您应该避免过多的嘲弄和存根。 http://blog.davidchelimsky.net/2011/09/22/avoid-stubbing-methods-invoked-by-a-framework/ http://blog.davidchelimsky.net/2011/09/22/avoid-stubbing-methods-invoked-by-a-framework/

Generally speaking you have two options: 一般来说,您有两种选择:

1) Use a dedicated test database with known data on which you can set your expectations - replace the DB with a "pristine DB" before starting testing. 1)使用具有已知数据的专用测试数据库,您可以在其上设置您的期望 - 在开始测试之前用“原始数据库”替换数据库。 This would be considered integration testing since you are in fact dependent on the database. 这将被视为集成测试,因为您实际上依赖于数据库。

2.) Make your code independent of the actual data store and pass in the dependency to the persistence layer. 2.)使代码独立于实际数据存储,并将依赖项传递给持久层。 For unit testing you can write (or mock out) a custom persistence layer/object that allows you to observe the state changes that your are unit testing. 对于单元测试,您可以编写(或模拟)自定义持久层/对象,以便您观察单元测试的状态更改。

A healthy mix of both depending on the scenario usually provides good coverage. 两者的健康组合取决于场景通常提供良好的覆盖。

Also instead of testing your Restful web service consider just delegating to a POCO within each service endpoint and then just test these POCOs directly - much easier testable and all you have left to do is verifying the mapping between service endpoint and POCO. 而不是测试您的Restful Web服务,只考虑委托每个服务端点中的POCO,然后直接测试这些POCO - 更容易测试,您还剩下要做的就是验证服务端点和POCO之间的映射。

My understanding is that if you do your tests in this order you can test all the verbs but there will be no additional data in the DB at the end. 我的理解是,如果按此顺序进行测试,则可以测试所有动词,但最后数据库中不会有其他数据。

POST ( add a new record)  
GET  ( fetch the newly added record)  
PUT/PATCH ( modify the newly added record)  
DELETE (delete the newly added record)  

Of course somebody else using the database at the same time might see transient values during the duration of the test. 当然,同时使用数据库的其他人可能会在测试期间看到瞬态值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM