This is really complex question. Each of your point is large enough to be a separate question so I will write only short summary:
Integration testing and unit testing don't replace each other. You always needs both if you want to have well tested application. Unit test is for testing logic in isolation (usually with help of mocks, stubs, fakes, etc.) whereas integration test is for testing that your components work correctly together (= no mocks, stubs or fakes). When to use integration test and when to use unit test really depends on the code you are testing and on the development approach you are following (for example TDD).
If your POCOs contains any logic you should write unit tests for them. Logic in your repositories is usually heavily dependent on database so mocking context and test them without database is usually useless so you should cover them with integration tests.
It is really dependent on what you expect from repositories. If it is only stupid DbContext / DbSet wrapper then the value of repository is zero and it will most probably not make your code unit testable as described in some referenced debates. If it wraps queries (no LINQ-to-entites in upper layer), expose access to aggregate roots then the meaning of repository is correct separation of data access and exposing mockable interface.
It is fully dependent on previous point. If you expose IQueryable or methods accepting Expression<Func<>> passed to IQueryable internally you cannot correctly mock the repository (well you can but you still need to pair each unit test with integration test testing the same logic). LINQ-to-entities is "side effect" / leaky abstraction. If you completely wrap the queries inside repository and use your own declarative query language (specification pattern) you can mock them.
Any testing is better then no testing. Many methodologies expects high density coverage. TDD goes even to 100% test coverage because test is written always first and there is no logic without test. It is about the methodology you are following and up to your professional decision to chose if you need a test for piece of code.
I don't think that there is any "read this and you will know how to do that". This is software engineering and software engineering is an art. There is no blue print which works in every case (neither in most cases).
发布评论
评论(1)
这是一个非常复杂的问题。您的每个观点都足够大,可以成为一个单独的问题,因此我只会写简短的摘要:
集成测试和单元测试不会相互替代。如果您想要经过良好测试的应用程序,那么您总是需要两者。单元测试用于单独测试逻辑(通常借助模拟、存根、假货等),而集成测试则用于测试组件是否能够正常工作(= 没有模拟、存根或假货)。何时使用集成测试以及何时使用单元测试实际上取决于您正在测试的代码以及您遵循的开发方法(例如 TDD)。
如果您的 POCO 包含任何逻辑,您应该为它们编写单元测试。存储库中的逻辑通常严重依赖于数据库,因此模拟上下文并在没有数据库的情况下测试它们通常是没有用的,因此您应该使用集成测试来覆盖它们。
这实际上取决于您对存储库的期望。如果它只是愚蠢的 DbContext / DbSet 包装器,那么存储库的值为零,并且它很可能不会使您的代码单元可测试,如一些引用的辩论中所述。如果它包装查询(上层没有 LINQ-to-entites),公开对聚合根的访问,那么存储库的含义就是数据访问的正确分离和公开可模拟接口。
这完全取决于前一点。如果您公开
IQueryable
或接受在内部传递给IQueryable
的Expression 的方法您无法正确模拟存储库(当然可以,但您仍然需要将每个单元测试与测试相同逻辑的集成测试配对)。 LINQ-to-entities 是“副作用”/泄漏抽象。如果您将查询完全包装在存储库中并使用您自己的声明性查询语言(规范模式),您可以模拟它们。
任何测试都比没有测试好。许多方法都期望高密度覆盖。 TDD 甚至可以达到 100% 的测试覆盖率,因为测试总是首先编写的,没有测试就没有逻辑。这是关于您所遵循的方法,以及您是否需要对一段代码进行测试的专业决定。
我不认为有任何“读完这篇文章你就会知道如何去做”。这就是软件工程,软件工程是一门艺术。没有适用于所有情况的蓝图(大多数情况下也不是)。
This is really complex question. Each of your point is large enough to be a separate question so I will write only short summary:
Integration testing and unit testing don't replace each other. You always needs both if you want to have well tested application. Unit test is for testing logic in isolation (usually with help of mocks, stubs, fakes, etc.) whereas integration test is for testing that your components work correctly together (= no mocks, stubs or fakes). When to use integration test and when to use unit test really depends on the code you are testing and on the development approach you are following (for example TDD).
If your POCOs contains any logic you should write unit tests for them. Logic in your repositories is usually heavily dependent on database so mocking context and test them without database is usually useless so you should cover them with integration tests.
It is really dependent on what you expect from repositories. If it is only stupid DbContext / DbSet wrapper then the value of repository is zero and it will most probably not make your code unit testable as described in some referenced debates. If it wraps queries (no LINQ-to-entites in upper layer), expose access to aggregate roots then the meaning of repository is correct separation of data access and exposing mockable interface.
It is fully dependent on previous point. If you expose
IQueryable
or methods acceptingExpression<Func<>>
passed toIQueryable
internally you cannot correctly mock the repository (well you can but you still need to pair each unit test with integration test testing the same logic). LINQ-to-entities is "side effect" / leaky abstraction. If you completely wrap the queries inside repository and use your own declarative query language (specification pattern) you can mock them.Any testing is better then no testing. Many methodologies expects high density coverage. TDD goes even to 100% test coverage because test is written always first and there is no logic without test. It is about the methodology you are following and up to your professional decision to chose if you need a test for piece of code.
I don't think that there is any "read this and you will know how to do that". This is software engineering and software engineering is an art. There is no blue print which works in every case (neither in most cases).