Stack Exchange Network

Stack Exchange network consists of 175 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
124

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 ...


87

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 ...


45

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, ...


27

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 ...


19

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. ...


15

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


12

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. ...


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 ...


11

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 ...


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

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 ...


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 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 ...


7

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 ...


7

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 ...


6

The whole point of the repository pattern is to allow you to abstract away the implementation behind a generic interface. You can use whatever method works best for your situation, and if you want to change it later, it shouldn't affect the rest of your application. Use whatever implementation works best (and is the easiest to understand and maintain).


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

> 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.


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

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 ...


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 ...


5

I think that exposing the IQueryable on your repository is perfectly acceptable during the initial phases of development. There are UI tools that can work with IQueryable directly and handle sorting, filtering, grouping, etc. That being said, I think that just exposing crud on the repository and calling it a day is irresponsible. Having useful operations ...


5

Please note that I only have minor experience with the .NET framework and that this answer only relates to the architecture part of your question. As far as I understood it, you are basically applying the following architectural patterns in your application: Layers: It seems you have a persistence layer (Repository Pattern), a business logic layer and a ...


5

it's kind of weird that I can have two repositories Get used to it. It's long been considered good practice to model your use cases explicitly. From the perspective of the application, it has a reference to a repository that plays the role of providing a reference to a particular flavor of aggregate root. So you might have interface Product { // ... ...


5

Okay. There is a lot to unpack here, but the I think the root cause of some of your confusion is stemming from starting this process with the physical model at the forefront. This commonly causes all sorts of issues for individuals first trying to implement DDD. The goal of DDD is to model the behavior of a system such that the result is a useful abstraction ...


5

The immediate problem I see here that it becomes hard to unit test the "UnitOfWork" with mock repositories. What if the line repoItem = new Repository<TEntity, object>(Context); needs to be replaced by ... new MockRepository for a meaningful test? So in case UnitOfWork just needs one or two, maybe 3 repos, you could try to inject them in the ...


5

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 ...


4

It looks like you are missing the concept of Unit of Work pattern in your DAL design. There are nice posts that explaining this concepts here: Unit of Work pattern - managing parent child relationships The Unit Of Work Pattern And Persistence Ignorance Unit of Work Pattern


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