单元测试时,是否必须使用数据库来测试CRUD操作?

发布于 2024-08-05 18:38:50 字数 96 浏览 4 评论 0原文

单元测试时,测试CRUD操作时是否必须使用数据库? sql lite 可以帮助解决这个问题吗?您是否必须以某种方式在内存中创建数据库?

我正在使用 mbunit。

When unit testing, is it a must to use a database when testing CRUD operations?
Can sql lite help with this? Do you have to cre-create the db somehow in memory?

I am using mbunit.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

沩ん囻菔务 2024-08-12 18:38:50

不。集成实际的数据库将是集成测试。不是单元测试。

是的,如果您无法以任何其他方式抽象(模拟)您的 DAL/DAO,您可以使用任何内存数据库,例如 SQLite 或 MS SQL Compact。

考虑到这一点,我必须指出,单元测试可以一直进行到 DAL,但 DAL 本身却不行。在集成测试中,DAL 必须使用某种实际的数据库进行测试。

No. Integrating an actual DB would be integration testing. Not unit testing.

Yes you could use any in-memory DB like SQLite or MS SQL Compact for this if you can't abstract (mock) your DAL/DAO in any other way.

With this in mind I have to point out, that unit testing is possible all the way to DAL, but not DAL itself. DAL will have to be tested with some sort of an actual DB in integration testing.

能否归途做我良人 2024-08-12 18:38:50

与所有复杂的问题一样,答案是:这取决于:)

一般来说,您应该将数据访问层隐藏在接口后面,以便您可以在不使用数据库的情况下测试应用程序的其余部分,但是如果您想测试数据访问实现本身?

在某些情况下,有些人认为这是多余的,因为他们主要使用声明性数据访问技术(例如 ORM)。

在其他情况下,数据访问组件本身可能包含一些您可能想要测试的逻辑。这可能是一件完全相关的事情,但您将需要数据库来做到这一点。

有些人认为这是集成测试而不是单元测试,但在我的书中,你怎么称呼它并不重要 - 最重要的是你从完全自动化的测试中获得价值,并且你绝对可以使用单元测试框架来驱动这些测试。

不久前,我写了关于如何在 SQL Server 上执行此操作。要记住的最重要的事情是避免使用一些“代表性数据”创建通用夹具的诱惑,并尝试在所有测试中重用它。相反,您应该在每次测试中填写数据并在测试后进行清理。

As with all complicated question, the answer is: It depends :)

In general you should hide your data access layer behind an interface so that you can test the rest of the application without using a database, but what if you would like to test the data access implementation itself?

In some cases, some people consider this redundant since they mostly use declarative data access technologies such as ORMs.

In other cases, the data access component itself may contain some logic that you may want to test. That can be an entirely relevant thing to do, but you will need the database to do that.

Some people consider this to be Integration Tests instead of Unit Tests, but in my book, it doesn't matter too much what you call it - the most important thing is that you get value out of your fully automated tests, and you can definitely use a unit testing framework to drive those tests.

A while back I wrote about how to do this on SQL Server. The most important thing to keep in mind is to avoid the temptation to create a General Fixture with some 'representative data' and attempt to reuse this across all tests. Instead, you should fill in data as part of each test and clean it up after.

铃予 2024-08-12 18:38:50

在单元测试时,测试 CRUD 操作时是否必须使用数据库?

假设您已经围绕所述 CRUD 操作提取了接口,并通过模拟或存根测试了使用所述接口的所有内容。现在剩下的代码块是一个 save 方法,其中包含一些用于绑定对象的代码和一些 SQL。

如果是这样,那么我会声明一个“单元”,并说您确实需要一个数据库,并且最好是至少能够很好地代表您的数据库,以免您陷入供应商特定 SQL 的困境。

我还会少量使用模拟来强制出现错误条件,但我不会仅使用模拟来测试保存方法本身。因此,虽然从技术上讲这可能是一个集成测试,但我仍然会将其作为单元测试的一部分。

编辑:错过了问题的 2/3 秒。对不起。

sql lite 可以帮助解决这个问题吗?

我过去曾在内存数据库中使用过,并且因为我使用的数据库和实时系统做了一些不同的事情或者它们需要相当长的时间来启动而被咬。无论如何,我建议每个开发人员都拥有一个开发人员本地数据库。

您是否必须以某种方式在内存中创建数据库?

在数据库中是的。我使用 DbUnit 来分散数据并使用 SQL 脚本手动使架构保持最新,但您可以只使用 SQL 脚本。拥有开发人员本地数据库确实会增加一些额外的维护,因为您拥有架构和数据集来跟上数据,但我个人认为这是值得的,因为您可以确保数据库层按预期工作。

When unit testing, is it a must to use a database when testing CRUD operations?

Assuming for a moment that you have extracted interfaces round said CRUD operations and have tested everything that uses said interface via mocks or stubs. You are now left with a chunk of code that is a save method containing a bit of code to bind objects and some SQL.

If so then I would declare that a "Unit" and say you do need a database, and ideally one that is at least a good representation of your database, lest you be caught out with vender specific SQL.

I'd also make light use of mocks in order to force error conditions, but I would not test the save method itself with just mocks. So while technically this may be an integration test I'd still do it as part of my unit tests.

Edit: Missed 2/3s of your question. Sorry.

Can sql lite help with this?

I have in the past used in memory databases and have been bitten as either the database I used and the live system did something different or they took quite some time to start up. I would recommend that every developer have a developer local database anyway.

Do you have to cre-create the db somehow in memory?

In the database yes. I use DbUnit to splatter data and manually keep the schema up to date with SQL scripts but you could use just SQL scripts. Having a developer local database does add some additional maintenance as you have both the schema and the datasets to keep up to data but personally I find is worth while as you can be sure that database layer is working as expected.

℉絮湮 2024-08-12 18:38:50

正如其他人已经指出的那样,您想要实现的不是单元测试,而是集成测试。

话虽如此,即使我更喜欢与模拟隔离的单元测试,集成测试也没有什么问题。因此,如果您认为这在您的上下文中有意义,只需将集成测试包含在您的测试策略中即可。

现在,关于您的问题,我将查看 DbUnit.NET。我不知道该工具的 .NET 版本,但我可以告诉您 Java 版本非常适合与数据库交互的测试。简而言之,DbUnit 允许您在运行测试之前将数据库置于已知状态并对表的内容执行断言。真的很方便。顺便说一句,我建议您阅读最佳实践页面,即使您决定不使用此页面工具。

As others already pointed out, what you are trying to achieve isn't unit testing but integration testing.

Having that said, and even if I prefer unit testing in isolation with mocks, there is nothing really wrong with integration testing. So if you think it makes sense in your context, just include integration testing in your testing strategy.

Now, regarding your question, I'd check out DbUnit.NET. I don't know the .NET version of this tool but I can tell you that the Java version is great for tests interacting with a database. In a few words, DbUnit allows you to put the database in a known state before a test is run and to perform assert on the content of tables. Really handy. BTW, I'd recommend reading the Best Practices page, even if you decide to not use this tool.

不再让梦枯萎 2024-08-12 18:38:50

实际上,如果您正在编写连接到数据库的测试,那么您正在执行集成测试,而不是单元测试。

对于此类操作的单元测试,请考虑使用某种类型的模拟数据库对象。例如,如果您有一个封装数据库交互的类,请从中提取一个接口,然后创建一个使用简单内存对象而不是实际连接到数据库的继承类。

Really, if you are writing a test that connects to a database, you are doing integration testing, not unit testing.

For unit testing such operations, consider using some typed of mock-database object. For instance, if you have a class that encapsulates your database interaction, extract an interface from it and then create an inheriting class that uses simple in-memory objects instead of actually connecting to the database.

陪你到最终 2024-08-12 18:38:50

如上所述,这里的关键是在运行测试之前让测试数据库处于已知状态。在一个实际示例中,我有几个在重新创建一组已知测试数据的测试之前运行的 SQL 脚本。由此,我可以测试 CRUD 操作并验证新行是否已插入/更新/删除。

As mentioned above, the key here is to have your test database in a known state before the tests are run. In one real-world example, I have a couple of SQL scripts that are run prior to the tests that recreate a known set of test data. From this, I can test CRUD operations and verify that the new row(s) are inserted/updated/deleted.

郁金香雨 2024-08-12 18:38:50

我编写了一个名为 DBSnapshot 的实用程序来帮助集成测试sqlserver数据库。

如果您的数据库架构经常更改,那么针对真实的数据库实例实际测试您的代码将会很有帮助。人们使用 SqlLite 进行快速测试(因为数据库在内存中运行),但是当您想要验证代码是否适用于数据库的实际构建时,这并没有什么帮助。

测试数据库时,您需要遵循类似于以下的模式:备份数据库、设置数据库进行测试、执行代码、验证结果、将数据库恢复到起始状态。

上述内容将确保您可以单独运行每个测试。如果您编写代码,我的 DBSnapshot 实用程序将简化您的代码。网。我认为它比 DbUnit.NET 更容易使用。

I wrote a utility called DBSnapshot to help integration test sqlserver databases.

If your database schema is changing frequently it will be helpful to actually test your code against a real db instance. People use SqlLite for speedy tests (because the database runs in memory), but this isn't helpful when you want to verify that your code works against an actual build of your database.

When testing your database you want to follow a pattern similar to: backup the database, setup the database for a test, exercise the code, verify results, restore database to the starting state.

The above will ensure that you can run each test in isolation. My DBSnapshot utility will simplify your code if your writing it .net. I think its easier to use than DbUnit.NET.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文