JUNIT服务测试和DAO层[关闭](JUNIT Test for Service and DAO Layer [closed])

我在项目中有分层架构,如Controller - > Service - > DAO。 我想为服务层编写JUnit测试用例。 现在,由于服务层将在内部调用DAO方法,为什么我要为DAO层编写不同的测试用例,因为它是内部测试的。

有人说我需要使用mockito来模拟DAO方法。 真的需要吗? 我不能在测试服务层方法时直接使用原始代码吗?

I have layered architecture in the project like Controller -> Service -> DAO. I want to write the JUnit test cases for service layer. Now as service layer will be internally calling DAO methods, why should I write different test cases for DAO layer as it is internally tested.

Some people say I need to mock DAO methods using mockito. Is it really required? Cant I directly use original code while testing service layer methods?

最满意答案

为您的服务提供一组测试,并为DAO提供一组单独的测试。

DAO测试应针对数据库,最好是内存数据库。 这不仅仅是因为它很容易创建它并在测试中将其拆除,但因为你会知道它是你的,没有其他人在改变它。 DAO测试将测试您的数据库映射和SQL是否正确。 您可以使用DBUnit使用测试数据初始化数据库,并在每次测试结束时验证数据库的内容,以便每个测试都可以针对已知数据集运行。 如果存在数据库级问题,那么单独的DAO测试将更容易区分,因为您将在DAO测试中看到它们,而不是在服务测试中看到它们。

可以使用针对DAO的模拟来测试服务。 因为测试不使用数据库,所以它们执行得更快(针对数据库的测试运行速度慢得多,甚至使用内存数据库),并且您可以在不降低测试速度的情况下运行许多不同的场景。 服务层通常是您的大多数复杂性所在,因此需要更多测试来覆盖它,如果这些测试可以快速运行则会好得多。

通常,您的DAO具有执行crud操作的方法,并且这些方法在服务中以不同方式被反复调用。 当您将数据库访问限制为仅限DAO测试时,可以最小化测试所需的数据库访问总量,并且测试运行得更快。

你谈到的是,有一组测试对数据库一直测试(服务和DAO)是非常诱人的,因为a)它一直在测试真实的东西,并且b)它似乎将是工作量减少(很多时候项目没有足够的抽象,你不能有效地单独测试事物,也没有时间把事情搞清楚)。 很多项目都是出于明智的原因做出同样的决定,并且他们都直接进入同样的tarpit测试陷阱,这些测试需要花费太长时间才能运行,并且会发现太多案例(因为开发人员在现有测试时添加更多测试用例时感到气馁已经花了太长时间)。 慢速测试导致代码覆盖率不佳和测试无效。

Provide one set of tests for your services, and a separate set of tests for the DAOs.

The DAO tests should be against a database, preferably an in-memory database. That's not just because it's easy to create it and tear it down in the test but because you will know it is yours and no one else is changing it. The DAO tests will test that your database mappings and SQL are right. You can use DBUnit to initialize the database with test data and to verify the contents of the database at the end of each test, so each test can run against a known dataset. With separate DAO tests if there are database-level problems those will be easier to distinguish, because you will see them in the DAO tests and not in the test for the services.

The services can be tested using mocks for the DAOs. Because the tests don't use a database they will execute faster (tests against a database run a lot slower, even using an in-memory database) and you can exercise a lot of different scenarios without slowing your tests down. The service layer is typically where most of your complexity will be so it will take more tests to cover it, it's much better if those tests can run quickly.

Typically you have DAOs with methods that do crud operations, and those methods get called over and over again in different ways in the services. When you limit database access to only the DAO tests you minimize the total amount of database access your tests need, and the tests run much faster.

What you talk about, having one set of tests that test all the way through (services and DAOs) against a database, is very tempting because a) it tests against real things all the way down, and b) it seems like it will be less work (also a lot of times the project doesn't have sufficient abstraction, you can't test things separately effectively, and there's no time to break things out). Lots of projects make the same decision for sensible reasons, and they all steer straight into the same tarpit trap of tests that take too long to run and which leave too many cases uncovered (because developers get discouraged about adding more test cases when their existing tests already take too long). Slow tests lead to bad code coverage and ineffective testing.

更多推荐