136

Your coworker is right that everything that can be unit-tested should be unit-tested, and you're right that unit tests will take you only so far and no further, particularly when writing simple wrappers around complex external services. A common way of thinking about testing is as a testing pyramid. It's a concept frequently connected with Agile, and many ...


89

One of my co-workers maintains that integration tests are all kinds of bad and wrong - everything must be unit-tested, That's a little like saying that antibiotics are bad - everything should be cured with vitamins. Unit tests can't catch everything - they only test how a component works in a controlled environment. Integration tests verify that ...


50

Returning IQueryable will definitely afford more flexibility to the consumers of the repository. It puts the responsibility of narrowing results off to the client, which naturally can both be a benefit and a crutch. On the good side, you won't need to be creating tons of repository methods (at least on this layer) — GetAllActiveItems, ...


31

Exposing IQueryable to public interfaces is not a good practice. The reason is fundamental: you cannot provide IQueryable realisation as it is said to be. Public interface is a contract between provider and clients. And in most cases there is an expectation of full implementation. IQueryable is a cheat: IQueryable is nearly impossible to implement. And ...


24

To get this out of the way, I am a big proponent of Entity Framework, but it does come with some drawbacks that you need to be aware of. I also apologize for the long answer, but this is a very hot topic with many opinions and many required considerations. For small application, a lot of these considerations don't matter, but for enterprise-grade ...


20

Realistically, you've got three alternatives if you want deferred execution: Do it this way - expose an IQueryable. Implement a structure that exposes specific methods for specific filters or "questions". (GetCustomersInAlaskaWithChildren, below) Implement a structure that exposes a strongly-typed filter/sort/page API and builds the IQueryable internally. ...


17

Unit tests don't catch all defects. But they are cheaper to set up and (re)run compared that other kinds of tests. The unit tests are justified by combination of moderate value and low-to-moderate cost. Here's a table showing defect detection rates for different kinds of testing. source: p.470 in Code Complete 2 by McConnell


14

No, they are not bad. Hopefully, one should have unit and integration tests. They are used and run at different stages in the development cycle. Unit Tests Unit tests should be run on the build server and locally, after the code has been compiled. If any unit tests fail, one should fail the build or not commit the code update until the tests are fixed. ...


14

No code reuse is usually understood as a selling point for microservices! the microservices can be developed and deployed independently different microservices can use different technologies, in particular different programming languages If this does not seem like an advantage – in particular if all microservices are developed by one team, using one ...


12

Database integration tests are not bad. Even more, they are necessary. You probably have your application split into layers, and it's a good thing. You can test each layer in isolation by mocking neighbouring layers, and that's a good thing too. But no matter how many abstraction layers you do create, at some point there has to be layer that does the dirty ...


12

I think you are conflating repositories and generic repositories. A basic repository just interfaces your data store and provides methods to return the data IRepository { List<Data> GetDataById(string id); } It doesn't leak the data layer into your code via an IQueryable or other ways of passing in random queries and provides a well defined ...


10

I believe Eric Evans wrote, "Models are neither right nor wrong; they are simply more or less useful". The question is, which model helps you solve the problem in a clean way. By just referring to the names of a number of classes, it is impossible for others to determine which model would help you solve your problem. But as to the why should you choose one ...


10

Repositories and their placement in the code structure is a matter of intense debate in DDD circles. It is also a matter of preference, and often a decision taken based on the specific abilities of your framework and ORM. The issue is also muddied when you consider other design philosophies like Clean Architecture, which advocate using an abstract ...


9

Ideally, if you really require a high level of security, the DB itself should not return any data for which the requester does not have the permission. So the answer in this case would be "neither" - the DB itself should provide an adequate security model, know about the permissions of a specific requester and restrict the data. However, most real world ...


8

There really is only one legitimate answer: it depends on how the repository is to be used. At one extreme your repository is a very thin wrapper around a DBContext so you can inject a veneer of testability around a database-driven app. There really is no real world expectation that this might be used in a disconnected manner without a LINQ friendly DB ...


8

should I return the data as an entity or domain objects/DTO Well that entirely depends on your use cases. The only reason I can think of returning a DTO instead of a full entity is if your entity is huge and you only need to work on a subset of it. If this is the case, then maybe you should reconsider your domain model and split your big entity into ...


8

It should satisfy SOLID principles A laudable goal, but does it help you satisfy any of your software's functional and non-functional requirements? The purpose of the SOLID principles is to help you write better code; not to be a goal, requirement, or metric in its own right. If you're spending you're time measuring your project's progress by observing and ...


7

Re: "UOW tracks the elements that needs be changed, and repository contains the logic to persist those changes, but... who call who?" You understand the basic responsibilities of these classes. You say that each of the articles, that you've read, connects them together in different ways. This implies that the decision about "who calls who" is up to you. I'...


7

> Should Repositories return IQueryable? NO if you want to do testdriven development/unittesting because there is no easy way to create a mock repository to test your businesslogic (= repository-consumer) in isolation from database or other IQueryable provider.


7

The author of the blog article you refer to is mainly concerned with the potential complexity that can arise from integrated tests (although it is written in a very opinionated and categorical way). However, integrated tests are not necessarily bad, and some are actually more useful than pure unit tests. It really depends on the context of your application ...


7

My understanding is: DAL (Data Access Layer) refers to a layer in your software that sits between your persistence technology and your application logic. Its purpose is to keep data access concerns separate from the rest of your application concerns. It is a general concept. Repository is a concept from DDD (Domain Driven Design). In DDD, a Repository ...


7

I vehemently opposed Vehemence makes others stop listening and, at the same time, limits our perception of the problems and their solutions. To my experience, we become vehement at defending or opposing ideas we don't fully understand. Although shared entities sound harmless to me, I opposed the idea of having shared repositories MS architectures ...


6

You need both. In your example if you were testing that a database in a certain condition, when the findByKeyword method is run you get the data back you expect this is a fine integration test. In any other code that is using that findByKeyword method you want to control what is being fed in to the test, so you can return nulls or the right words for your ...


6

I've faced such choice as well. So, let's summarize positive and negative sides: Positives: Flexibility. It's definitely flexible and convenient to allow client side to build custom queries with just one repository method Negatives: Untestable. (you will be actually testing the underlying IQueryable implementation, which usually your ORM. But you should ...


6

From a pure architecture standpoint, IQueryable is a leaky abstraction. As a generality, it provides the user with too much power. That being said, there are places where it makes sense. If you are using OData, IQueryable makes it extremely easy to provide an endpoint that is easily filterable, sortable, groupable... etc. I actually prefer to create DTO's ...


6

There's a sizable community of folks who use CQRS to implement their domains. My feeling is that, if the interface of your repository is analogous to the best practices used by them, that you won't go too far astray. Based on what I've seen... 1) Command handlers usually use the repository to load the aggregate via a repository. Commands target a single ...


6

Most of the arguments you mention wrongly attribute to the Repository pattern features that it doesn't have. Conceptually, a Repository as originally defined in DDD is just a collection of objects that you can search or add to. The persistence mechanism behind it is abstracted out, so as a consumer you get the illusion that it's an in-memory collection. A ...


6

A. Where can I place the validation? Regardless of your design there are two places where validation code goes: Near input Near use You put validation near input so that you can show the user the mistake quickly and get a correction timely. Also so that you understand the users context well. You put validation near use to protect against the many wild ...


6

Your repository doesn't break the "clean architecture", which identifies entities as the core, requires dependency inversion, but doesn't impose to use repositories. But your repository seems to break the clean code principles, and in particular: the single responsibility principle: you pack together things that have different reasons to change: ...


6

Is it acceptable to invoke business logic inside the repository layer? The DDD police are not going to come and kick down your door. But... The motivation for the repository pattern is to "decouple application and domain design from persistence technology". So adding domain logic behind the repository interface rather defeats the purpose. It also makes ...


Only top voted, non community-wiki answers of a minimum length are eligible