如何对按日期范围返回文章的查询进行单元测试?
假设我有一个文章表,我想为返回所有即将过期的文章的方法编写一个测试。
我将如何为此编写单元测试?如果我模拟该方法返回的文章集合,那它怎么是单元测试呢?
我的意思是我想确保它返回正确的文章数据范围?
有人可以澄清这一点吗?
Say I have a articles table, and I want to write a test for the method that returns all articles that are about to expire.
How would I go about writing a unit test for this? If I mock the collection of articles that the method returns, how is that a unit test?
I mean I want to make sure it returns the correct data range of articles?
Can someone clarify this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您正在测试数据访问层本身,您确实可能需要访问一些数据。许多人认为涉及外部依赖项(例如数据库)的测试是“集成”测试而不是“单元”测试——这并不意味着它们不重要。
一种选择是使用轻量级或内存数据库,例如 SQLite。作为设置测试的一部分,使用一组已知数据为数据库播种。然后您可以以受控方式安全地测试结果。
您需要控制的另一个因素:当您创建依赖于当前日期的内容时(如本例所示),您需要一种方法来注入假的“当前日期”以使测试更容易 - 不要只需在数据库中使用“SYSDATE”或等效内容,否则您的测试将变得更加困难(您的测试数据将不得不根据日期进行更改)。
If you're testing the data access layer itself, you will indeed probably need to access some data. Many people consider a test that hits an external dependency such as a database to be an "integration" test rather than a "unit" test -- which doesn't mean they aren't important to do.
One option is to use a lightweight or in-memory database such as SQLite. Seed the database with a set of known data as part of setting up your test. Then you can safely test the results in a controlled way.
Another factor you'll want to control: when you're creating something that depends on the current date (as in this instance) you'll want a way to inject a fake "current date" to make testing easier -- don't just use "SYSDATE" or the equivalent in your database or your testing will be much harder (your test data will have to change depending on the date).
我通常有一些由单元测试框架驱动的集成测试,这些测试适用于一组确定的数据(包括为每个测试运行设置数据的脚本,如此处所述)。这样您就可以准确地知道在给定日期范围内应返回多少(以及哪些)文章,然后您还可以为其编写测试。
I typically have some integration tests that are driven by the unit test framework, and that works on a determined set of data (including scripts to set up the data for each test run, as described here). That way you can know exactly how many (and which) articles that should be returned for a given date range, and then you can also author a test for it.
如果您模拟它,那么它就是一个单元测试,因为您正在测试尽可能少的功能。
如果你不模拟它,而是针对实时数据库,正如 Dror 所说,这就是一个集成测试。
If you mock it, it's a unit test because you're testing the smallest amount of functionality possible.
If you don't mock it, and go against a live database, as Dror said, it's an integration test.
无法“单元测试”数据访问层,而是可以编写一个“集成测试”来设置一个简单的数据库查询并使用断言来检查结果。
您还需要在测试后运行一个 clean 函数,以确保数据库恢复到其初始状态。
如果您想检查业务逻辑 - 即如何处理结果,则使用模拟从查询创建假返回。
There is no way to "unit test" data access layer instead you can write an "integration test" that would setup a simple database query it and use assertions to check the result.
You also need to run a clean function after the test to make sure that the database is restored to it's initial state.
In case you want to check business logic - i.e.erhow the results are handled then use mocks to create fake retuns from the query.
正如前面提到的,这种类型的测试确实是集成测试。您可以使用 MSTest 或 NUnit 作为测试运行程序,但是一个好的经验法则是将这些测试分离到各自的程序集或类别中,这样它们就不会在每次运行快速单元测试时都运行。要完成此集成测试应该不是很困难,您需要执行以下操作:
但需要注意的是,如果您没有足够的良好实践来快速轻松地设置系统,那么这些类型的测试可能会非常令人沮丧,因为集成测试非常依赖于整个系统的运行状态。成功通过某些“状态”。使这些类型的测试可重复且易于运行将使未来的集成甚至整个系统范围的测试更容易实施。
This type of test would indeed be an integration test as mentioned previously. You could either use MSTest or NUnit as the test runner, however a good rule of thumb would be to separate these tests out into their own respective assembly or category so they are not ran every time your fast unit tests are ran. To pull off this integration test should not be very difficult, you would would need to do something like the following:
Just as a word of caution though is that these types of tests can be very frustrating if you do not have a lot of good practices in place for quick and easy setup of your system since integration tests rely so much on the whole system being at a certain "state" to pass successfully. Making these types of tests repeatable and easy to run will make future integration and even full system wide tests easier to implement.