No video

The Common Entity Framework Mistake You MUST Fix

  Рет қаралды 51,267

Nick Chapsas

Nick Chapsas

Күн бұрын

Use code TDD20 and get 20% off the brand new Test-Driven Development course on Dometrain: dometrain.com/...
Get the source code: mailchi.mp/dom...
Become a Patreon and get special perks: / nickchapsas
Hello, everybody, I'm Nick, and in this video I'll talk about one of the most common mistakes I see people make when they write integration tests about their applications that use Entity Framework Core.
Workshops: bit.ly/nickwor...
Don't forget to comment, like and subscribe :)
Social Media:
Follow me on GitHub: bit.ly/ChapsasG...
Follow me on Twitter: bit.ly/ChapsasT...
Connect on LinkedIn: bit.ly/ChapsasL...
Keep coding merch: keepcoding.shop
#csharp #dotnet

Пікірлер: 170
@bogdanbara1496
@bogdanbara1496 10 ай бұрын
There's another important point: using different database providers in integration tests vs provider used for deployments can also miss bugs due to different behaviors of database providers. I've had a situation where I've missed some bugs (can't recall exactly what bugs) due to using sqlite in my integration tests while my deployments were using Microsoft SQL Server.
@megaman2016
@megaman2016 10 ай бұрын
That's exactly the point
@jangohemmes352
@jangohemmes352 10 ай бұрын
That's definitely a testing no-no, good point
@RaMz00z
@RaMz00z 10 ай бұрын
that means that you use EF to do too many things. I do agree that sqLite not having constraints can be cumbersome, but you should validate your constraints in the code anyways. Honestly, while I agree that you shouldn't use the InMemory provider (Microsoft says so as well), sqLite is a perfectly valid DB for testing, and incredibly faster that any integration test. Because people don't have beast PC like Nick in most cases... I worked like this for 4 years, on an app that was 8 years old. Not once it happened that we had an issue withj not using a real DB. But we wrote the code that EF do nothing fancy so it could be possible.
@bogdanbara1496
@bogdanbara1496 10 ай бұрын
@@RaMz00z The thing is that at least one of the bugs we missed due to using sqlite was exactly a bug in our constraints. Or, rather, a missing one: someone missed a uniqueness constraint (as far as I remember) that we were enforcing in EFCore, sqlite had no issue with the fact that non-unique data was being inserted (a peculiarity of it we didn't know of at the time), but when we deployed of course SQL Server had issues with it. And while we caught it early in staging, the idea that this should've been caught by integration testing but wasn't because database providers can behave differently stuck with me.
@RaMz00z
@RaMz00z 10 ай бұрын
@@bogdanbara1496 one out of how many? Don't justify the investment in my opinion
@dmitrykim3096
@dmitrykim3096 10 ай бұрын
One thing is that sometimes not perfect integration tests are better than no integration tests at all.
@nickchapsas
@nickchapsas 10 ай бұрын
I 100% agree. It's about going that extra mile and getting the most out of them
@modernkennnern
@modernkennnern 10 ай бұрын
Depends; If you have no tests you have no belief of whether it works or not. if you have a flaky test you have a false sense of security
@dmitrykim3096
@dmitrykim3096 10 ай бұрын
@@modernkennnern flaky tests are not just not perfect, they are broken. I was talking about tests that don't cover all the parts exactly as some things just can't be mocked, not all databases for example have a good dockerizable solution. So testing 80 percent of parts of app is better than not testing anything at all for me.
@dacke9000
@dacke9000 10 ай бұрын
@@nickchapsas again I understand about integration tests but I'm looking for unit tests. I don't want to talk to the database I don't want to test any framework I want to test my provider and so therefore I want to mock the responses from the DB context
@DaveMuller
@DaveMuller 10 ай бұрын
@dmitrykim3096 I don't agree with that. It can be deceptive to have fake integration tests. Keep the fake integration test but don't call it an "integration test" or you'll think that integration works when it may not.
@peryvindhavelsrud590
@peryvindhavelsrud590 10 ай бұрын
We actually do use in-memory tests to test the API endpoints, in some cases we also use an in memory SQLite database to simulate a SQL database to check some queries that actually fails with the in-memory EF-Core Database. But we do treat all of them as unit-tests, not integration tests. The Integration tests are executed in a dev environment with the API calls including the network.
@stevelang2416
@stevelang2416 10 ай бұрын
We take a slightly different approach by creating a DB transaction owned by the test, creating DB contexts that uses that transaction, and registering a DB context with DI. At the end of the test we rollback when the test and its transaction is disposed. We actually create three DB context, the 'Assign' DB context for setting up test data, the 'Act' DB context which is the one registered with DI, and the 'Assert' DB context to verify data changes.
@Thorarin
@Thorarin 10 ай бұрын
Why are you reregistering the CustomerService? Scoped services can use singletons just fine.
@slowjocrow6451
@slowjocrow6451 10 ай бұрын
Yes I didn't understand that bit, I hope Nick sees this and clarifies
@SuchHeroicNonsense
@SuchHeroicNonsense 10 ай бұрын
Tried to do something like this back in 2017/2018 with different tech but manager at the time rejected it. I always thought it was a bit crap to have to script the setup for the tests outside of the test framework. This is much easier and much more intuitive for both local development and running integration tests as part of CI/CD, and does away with having to maintain these scripts. Thank you Nick
@nocgod
@nocgod 10 ай бұрын
I think you should also deal with migrations, seeding and test parallelization
@nickchapsas
@nickchapsas 10 ай бұрын
Which is all addressed by the container approach
@nocgod
@nocgod 10 ай бұрын
@@nickchapsas well...yeah... but you've got to show this stuff. otherwise, all tests are always green field tests, migrations are automatically applied (no one does that IRL) and if tests aren't parallelized you aren't testing data concurrency
@GlebWritesCode
@GlebWritesCode 10 ай бұрын
Agree. My 2c: 1) Sqlite has other problem, IIRC it does not support mapping DateTimeOffset properties + you can only run one write transaction at a time 2) You need to use same approach when testing database migrations
@Kirides
@Kirides 10 ай бұрын
For the first point, you can add a conversion for DateTimeOffset to long/string and it will work ok most of the time and write transactions should be fast anyway, you wouldn't write any code that locks two parts of the database with separate DbConnections just to ... why? Though i must agree, that for cases where you _need_ the Offset-Part of DateTimeOffset, a real Db integration (MariaDb, MsSql, PgSql, ...) is much better. And if you get around to implement CTE (common table expressions, recursive DB Calls, due to hierarchical data retrieval) you have to use Raw SQL anyways and every DB Provider has it's own way of writing CTEs in a way or another
@johannesmogashoa1320
@johannesmogashoa1320 10 ай бұрын
Damn, this is a good video. Thank you, thank goodness you released it before I started any integrations tests.
@Osirus1156
@Osirus1156 10 ай бұрын
Another good package I’ve used is doomDb. It creates a new db for you and removes it right away after the test. You can connect to the db and inspect it too if you break before it tears it down if you are getting issues you need to debug from the db itself.
@E4est
@E4est 10 ай бұрын
We currently don't have the ability to run containers in our environment, so our solution to this problem is to spin up a LocalDb in our CI and populate that with our test data. It's not ideal since LocalDb is SQL Express compared to our SQL Standard in production, but it's close enough and probably better than using InMemory. 😅
@RaMz00z
@RaMz00z 10 ай бұрын
Very few differences between the two indeed, except if you have a DBA that go deep into tweaking your SQL Server instance
@JeffreyLimauro
@JeffreyLimauro 10 ай бұрын
I also prefer to use LocalDb, as it respects entity models configurations and foreign key restraints than the in-memory databases.
@fnasserebar
@fnasserebar 10 ай бұрын
Did you know that Nick Chapsas is wearing chaps when he records his videos?
@neipo
@neipo 10 ай бұрын
And sells chaps as a service - Chapsaas
@StuartQuinn
@StuartQuinn 10 ай бұрын
Sassy.
@readonlyden
@readonlyden 10 ай бұрын
That's a really good approach. I use repositories and unit tests if the business logic itself is very complex (but one can use functional approach here as well without any repositories and mocks) and use integration tests with testcontainers for everything else. Works like a charm
@justgame5508
@justgame5508 10 ай бұрын
I do basically the same thing. If their is complex business validation (such as different reads/writes depending on certain conditions such as UserType) I’ll use repositories otherwise just raw dog the EF statements and test with test containers and docker
@LordSuprachris
@LordSuprachris 10 ай бұрын
Hi Nick. This is exactly how we are doing integration tests in the company I'm working, for the same reasons you explain in your video. :)
@iaswaiss
@iaswaiss 10 ай бұрын
Having a descriptive title about the video topic will make it easier for people to search for this video in the future. Thanks for the video :)
@nickchapsas
@nickchapsas 10 ай бұрын
KZbin is smart at recommending based on video transcription so no SEO is lost.
@garcipat
@garcipat 10 ай бұрын
In our projectcwe use sqlite with an inmemory db. This was also recommended by ms as an alternative. But will take a look into that testcontainer. We support multiple providers, thats why its even harder to cover everything.
@GandalfThePlaid
@GandalfThePlaid 10 ай бұрын
MS's own documentation says it shouldn't really be used. "The in-memory provider will not behave like your real database in many important ways. Some features cannot be tested with it at all (e.g. transactions, raw SQL..), while other features may behave differently than your production database (e.g. case-sensitivity in queries). While in-memory can work for simple, constrained query scenarios, it is highly limited and we discourage its use."
@chadobrien3352
@chadobrien3352 10 ай бұрын
Not gonna lie, was put on edge when he said you are using InMemoryDatabase wrong. But then when he finally said it's an integration test I was relieved. We improved our data access layer services' unit tests speed by implementing the in memory dboptionsbuilder. Excellent video.
@Sahuagin
@Sahuagin 10 ай бұрын
I agree about "in memory database", it's neither a unit test nor a proper integration test. instead you should be able to test the logic of your LINQ queries using LINQ To Objects (by injecting EF and mocking it) (these are true unit tests), and then can also test the translation of your LINQ queries using a real DB connection and a TransactionScope. these tests do not need to test the logic of your queries, only that they can be translated. you want to use the same provider as your production release or else you aren't testing the correct translation. (in-memory database or SQLite instead of SQL Server will give you wrong results.)
@mohammedelsuissey1745
@mohammedelsuissey1745 10 ай бұрын
No Nick, sorry Integration test is testing the integration between components in your project, and the integration between your project and the other parties, making sure EFCore will build a valid query for the specific provider is an EFCore function testing, and it's out of your project's scope, we use EFcore because it's heavily tested and it has proven working. However your point is valid on the basis that you need to test against the vendor's database because different database types might behave differently.
@johannormen
@johannormen 10 ай бұрын
First of all, a good post as usual :) But to this one I respectfully disagree. Test categorization is often context-dependent and can vary from one organization to another. In our enterprise setup, we use a Pact-flow approach to mock external dependencies, focusing on the interaction within our services. We label these as 'integration tests,' which they genuinely are, even though the term 'functional tests' could be applied. However, calling them 'component tests' would be misleading. We're not merely testing individual components; we're examining how they integrate within a bounded context. Furthermore, we employ 'smoke tests' for end-to-end (E2E) verification. These tests engage all dependent services to ensure the entire system functions as expected. So, what you call a test is often shaped by the organizational and contextual framework you operate within and also what limitations you have to call external services. "Integration testing (sometimes called integration and testing, abbreviated I&T) is the phase in software testing in which the whole software module is tested or if it consists of multiple software modules they are combined and then tested as a group. Integration testing is conducted to evaluate the compliance of a system or component with specified functional requirements.[1] It occurs after unit testing and before system testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.[2]"
@coolmn786
@coolmn786 10 ай бұрын
Does your dometrain course include End to End Testing? Would like that course as well!
@dxs1971
@dxs1971 10 ай бұрын
How can you use docker in AWS pipeline CI/CD?
@himagainstill
@himagainstill 10 ай бұрын
Surely the point of using the dummy database is that if you use a real database, you're testing the database driver rather than your code, and if you're using EF, you generally assume the database driver works. Your application tests should not fail because your test db is down, or because you're unable to spin up a container - neither of those has anything to do with your application, nor are they integration points or part of the system under test.
@queenstownswords
@queenstownswords 10 ай бұрын
Yes! YES! Use a read test database. I have personally seen many times when a configuration file was 'tweaked' or a table was updated without communications to the developers - breaking integration tests... Listen, if an org is to cheap to pay to host a 'real' test database, expect them to be to cheap to give you a salary increase. period.
@killpopers
@killpopers 10 ай бұрын
Its a nice idea but only if you can have docker installed ive worked places where that was not allowed 😢 in that case your left with option a
@RiccardoSantoro
@RiccardoSantoro 10 ай бұрын
Side note, it's better to create an ICollectionFixture because (at least in azure devops) testcontainer won't run multiple dbcontainer (one for class using the IClassFixture)
@user-no3uf4wc5x
@user-no3uf4wc5x 10 ай бұрын
Totally agree, for me it's been pretty obvious, that in memory db is not really testing anything. Used existing database approach a lot.
@renynzea
@renynzea 10 ай бұрын
Targeting a real database is something I have done for a while. There is so much code that will run in-memory that won't run against a database in EF. Where I work we have tests spin up the database from a backup and apply migrations, because it is a 18+ year-old legacy application running against SQL Server with too much data to replicate. Also verifies our migrations that way. The "bad thing" is we use tests to spin up the database to test code out outside of tests. But it is easy and since it applies the migrations we can drop just the db, switch branches, run a single test, and boom we have a new database exactly spec'd to that branch that we can develop against.
@thedreadedgman
@thedreadedgman 10 ай бұрын
and the linq to SQL parsing and conversion that EF does can appear correct at build time but fail at runtime as I've discovered... so it's important to test those.
@isnotnull
@isnotnull 10 ай бұрын
What if you have limited human resources on the project? I always try to write simple integration tests first without any unit tests. What is your recommended approach?
@asteinerd
@asteinerd 10 ай бұрын
One thing I don't get is the switch from Scoped to Singleton on the context when configuring the `TestServices()`; A unit test checks the flow of the individual unit, it doesn't really care about the data; just that it functions with the concepts of a few good and bad scenarios. Integration tests are more about the data-flow; actually taking data-at-rest and making it move through the logic to make sure everything works as intended; the data is more important than a unit test; but the where it comes from still unimportant... HOWEVER; there are some complex scenarios that are data-first (not code-first as EF prefers) that running scoped is ideal; and a singleton would potentially break when jumping across multiple contexts (yes, I know I know; microservice the data/service and blah blah blah; we don't all have that option). Thoughts?
@ozsvartkaroly
@ozsvartkaroly 6 ай бұрын
A question about integration tests: what about emulators in general those run on the developer's machine? For example, the CosmosDb emulator can be used for "integration"(?) testing, and in many ways it is similar (but not same!) to a real database but it is not a real one; so should emulators be used for integration testing? Or if not, when they should be used? Functional tests would be using mocked/in-memory implementations I guess.
@megasuperlexa2
@megasuperlexa2 9 ай бұрын
why did you go for singleton for your in-memory context? just leave it scoped, so you dont have to change service reigistration
@Snikersano
@Snikersano 10 ай бұрын
really good video, i miss some bit more detailed explaining on what bugs it can lead to but anyways great vid. I remember reading about that somewhere at MSDN the other day where microsoft actually encourages to use exactly same provider as on production, as there can be collation problems and such, especially in memory database tends to skip unique index checks. nice lesson regardless keep it up.
@andresrossini6389
@andresrossini6389 10 ай бұрын
Hey Nick! What does the IApiMaker Interface do? I mean, the name is obvious, but what exactly do that one? Because when I downloaded the code, the interface is clean, thanks dude. You rock it on your videos!
@eesaaphilips9271
@eesaaphilips9271 10 ай бұрын
This is great; test containers are a big time saver. I wonder how you'd approach having integration tests with something like dapper. I'm guessing you could use DI to inject IDbConnection in the same way you do the db context here?
@GlebWritesCode
@GlebWritesCode 10 ай бұрын
Can you talk about using retries with EF Core (and DBs in general)? I've seen several occasions where people would just retry everything including writes
@alirezanet
@alirezanet 10 ай бұрын
for integration test I agree this is the best way to do it, but for unit tests also I don't use InMemory db mainly because it doesn't support relational data so it is useless in my opinion, I generate an interface using source generator for my dbcontext and mock the interface anywhere I want.
@a__random__person
@a__random__person 10 ай бұрын
ehhh i partially disagree here. ideally you wouldn't use dbcontext in the services, you would use it behind a repository. Then you can swap to memorydb, mssql, postgresql, nosql, etc data storage you want.. and test the interfaces/contracts between them. This way you can work fast with memorydb to test your platform, while having separate tests for your data access layer... which can measure query performance for example. Those can all be run in CI/CD but for locally running tests fast during development, nothing wrong with in memory db here unless of course you're writing code related to db.
@mdrtoffee
@mdrtoffee 10 ай бұрын
The one mistake you can make is using EF in the first place. No reason to use it over something like Dapper for example.
@stefanotorelli3688
@stefanotorelli3688 10 ай бұрын
Very interesting!
@llindeberg
@llindeberg 10 ай бұрын
So one database container spins up per test? What about 1000 tests? How slow is that? Very relevant
@neilbroomfield3080
@neilbroomfield3080 10 ай бұрын
I presume this works well with EF code-first, but what if you're using database first, how to you scaffold a test database with the correct up-to-date schema etc.?
@ryanboggs3924
@ryanboggs3924 10 ай бұрын
So the way I understand it is that for integration testing with EF (or EF core), we shouldn't be modifying the db provider, as demonstrated in the video with the pg container. Based on that, would it be a safe assumption with SQL Server projects and without access to create test db containers to use localdb for integration testing instead?
@slowjocrow6451
@slowjocrow6451 10 ай бұрын
Is there an MS SQL test container? Or only postgres?
@condar15
@condar15 10 ай бұрын
Does this mean you need to run migrations as well each time you run the integration tests? Also not all databases can be containerized, the big one I'm aware of is Cosmos, if you're backing your repositories you can't create a container (well, you can, but it has weird requirements to configure certificates each time it runs which gets very weird very fast, and isn't at feature parity).
@nickchapsas
@nickchapsas 10 ай бұрын
You don't have to. Most people create container images with their migrations pre-executed so they can go straight to the test execution
@joshuawillis7874
@joshuawillis7874 10 ай бұрын
Have you or do you think it would be a neat idea to go over the Repository and UnitOfWork patterns to use mocked DataSources (and also open up data provisioning for extensibility) in our C# unit tests?
@haxi52
@haxi52 10 ай бұрын
I would like to see an example of where an in-memory db would pass a test, where pgsql would not.
@arjix8738
@arjix8738 10 ай бұрын
I don't test my code, so I never made this mistake.
@F2H16
@F2H16 10 ай бұрын
I would be really interested to buy a couple of courses from dometrain but the prices are too high. I know good products do cost more but still asking do you have any plan to reduce the prices any time soon ?
@AlfredoLopez-mc8ds
@AlfredoLopez-mc8ds 10 ай бұрын
awesome, but it's not very dificult to integrate in a devlab, for example in azure devops, and if you need to change that CI to another provider like aws may be generates problems?
@hermanussen
@hermanussen 10 ай бұрын
This video is too harsh. There are perfectly good use cases for using the inmemory provider. Writing e2e integration tests isn't one of them, agreed. But that doesn't mean you couldn't use it in automated UI tests for example. Integration testing can be hard, and testing only part of it can be a perfectly valid approach (provided it is a conscious decision based on good arguments).
@martinrj30
@martinrj30 10 ай бұрын
will @nickchapas do a vid on Respawner with a Sql Container?
@user-bx2er2zx5u
@user-bx2er2zx5u 10 ай бұрын
Will you make EF Core and Dapper course for dometrain?
@nickchapsas
@nickchapsas 10 ай бұрын
EF Core is coming by the middle of November. No plans for Dapper at this point
@user-bx2er2zx5u
@user-bx2er2zx5u 10 ай бұрын
@@nickchapsasThank you!
@nezqwe4818
@nezqwe4818 10 ай бұрын
hi, for the courses on dometrain. How up to date is it? Be nice to see uploaded date or updated date :(
@nickchapsas
@nickchapsas 10 ай бұрын
They are all always up to date. If they are not, they are being re-done
@VladyslavHorbachov
@VladyslavHorbachov 10 ай бұрын
Extremely useful video
@AlwaresHUN
@AlwaresHUN 10 ай бұрын
Wow I assumed for years that EF is working like this with inmemory, but didn't know the details. But integrating this docker solution to a CI/CD is not trivial.
@samuelschwager
@samuelschwager 10 ай бұрын
Last time I checked the in memory provider cannot do stored procedures, that alone could be a reason to avoid it...
@RaMz00z
@RaMz00z 10 ай бұрын
Don't do stored procedures. There, problem solved.
@jeroen7362
@jeroen7362 10 ай бұрын
Stored procedures itself are a reason to avoid them. Those should have been forbidden long ago. Same goes for triggers and functions in databases.
@tunawithmayo
@tunawithmayo 10 ай бұрын
I feel like you are talking faster than you used to, and you aren't the only creator that I have noticed this with. I know I can just watch at 75% speed, but is there something about the platform that's causing y'all to cram 15 minutes of information into 10?
@finickyflame
@finickyflame 10 ай бұрын
I thought you were referring to people using IEnumerable in their interface that is implemented by the DbSet behind. I've seen some projects make that mistake and it's a huge performance issue because everything is retrieved in-memory instead of queried on the database.
@nickchapsas
@nickchapsas 10 ай бұрын
Oh that's a great topic for a video!
@Great_Critic
@Great_Critic 10 ай бұрын
Once I had a situation when wanted to implement kind of generic repository with first or default method. The method was taking a Func as first argument, and was passing it to corresponding method of DbSet. Then some time after I've noticed that filtration was not performed in the db, but in memory. And I've found out that there are two firstOrDefault extensions for Context.DbSet. First one is for IEnumerable and takes func, second was actually for DbSet and took Expression. The second option was correct one, which is to be used for linq transcription into SQL.
@vincenthamelin6115
@vincenthamelin6115 10 ай бұрын
I think Nick Chapsas’s father is Chuck Norris.
@anthonytrad
@anthonytrad 10 ай бұрын
Test containers haven't really worked for me. Since i have to maintain the docker compose file anyway for local debugging, i see little value to have 2 ways of spinning things up.
@nickchapsas
@nickchapsas 10 ай бұрын
Using a test specific docker-compose file and using something like FluentDocker to run it as part of your tests is a perfectly valid way to do this too
@RaMz00z
@RaMz00z 10 ай бұрын
You can use your real docker-compose file to spin up your test container. Actually that's what we do
@fibs9456
@fibs9456 10 ай бұрын
Don't you like the new Rider UI?
@tracetv8115
@tracetv8115 10 ай бұрын
Is there also a problem for unit tests?
@logicaldistraction
@logicaldistraction 10 ай бұрын
mhmm... microsoft owns MSSQL. they could just create an in memory version that relies on queries to fail in the same way... I personally would not differ so much between SQL and PostgreSQL altough there are some differences when using e.g. vectors or jsonb.
@phreakadelle
@phreakadelle 10 ай бұрын
Exactly! :)
@GregKedzierski
@GregKedzierski 10 ай бұрын
How's it going to work if you're running your tests in parallel?
@nickchapsas
@nickchapsas 10 ай бұрын
Depends on your setup. It can work fine but it means you'll have one container per test so you'll need to set a max degree of parallelization limit so you don't exhaust resources.
@pilotboba
@pilotboba 10 ай бұрын
It's not really an EF mistake people are making though. :)
@matthewrossee
@matthewrossee 10 ай бұрын
Can someone explain to me the key difference between integration tests and functional tests? It seems as if there were a thin line between these two. I mean, I know pretty good how to tell the difference between unit tests and integration tests, but when does the integration become functional? The definitions on the Internet are a little bit vague to me.
@RaMz00z
@RaMz00z 10 ай бұрын
Integration goes end to end, ie from real HttpClient to real DB. Functional go through the functional layers, ie from the Command to the Domain. In functional testing you don't do mocking like in integration, but you can use a provider like sqLite (except if you do weird things with EF that won't be compatible) Idea is, you actually can do Functional Testing in Integration, but it will take forever to run, so I'd discourage it personnally. And the big difference to me is how you write them. If you don't do Gherkin, it's not functional to me. Also, your Domain people should be able to write them. Look at Specfloww, it's da bomb for functional testing.
@matthewrossee
@matthewrossee 10 ай бұрын
@@RaMz00z „in functional you don’t do mocking like in integration” What do you mean by that? Everywhere I read about it, they say you shouldn’t mock any services etc in integration tests
@gbjbaanb
@gbjbaanb 10 ай бұрын
@@matthewrossee nonsense. You can test as much or as little as you like. Integration tests do not have to be end-to-end. Ignore the high priests of code scripture who will call you a heretic. eg. If you test the calls from client to server and it works, then you can integration test the server to DB using a helper tool to replay the data calls without the client being involved just fine. The whole point is not to "test the one true way", but to test so it works. However that is easiest for you, do it.
@garcipat
@garcipat 10 ай бұрын
I heard today inmemory provider is depricated
@xpflutebox
@xpflutebox 10 ай бұрын
this could've been a short
@discbrakefan
@discbrakefan 10 ай бұрын
The way to avoid this problem is to test in prod
@astrowalker2629
@astrowalker2629 10 ай бұрын
Your are mixing concepts, and your assumptions as the effect are wrong -- you are not switching modes of DB, you are switching DB engines completely. For example as code shown in 6:33 you could have in test MySQL DB while in production you would use PgSQL, both would use disk but does it mean such switch is valid? In short, storage medium (memory, disk, rabbit holes) is not important, DB engine + driver is.
@nickchapsas
@nickchapsas 10 ай бұрын
That's exactly what I'm saying in the video. That the integration point is both the translation of your C#/LINQ to the query appropriate for the db engine AND the DB engine itself.
@bitzartdev
@bitzartdev 10 ай бұрын
I dislike the fact that this video continues on the 'This is not a REAL {insert_test_type} test' trend, which is already too overgrown in the community. Just write your tests and have them check what needs to be checked. Why overcomplicate things to the point where no one writes tests because it's "too difficult"? My tests are usually somewhere in-between unit tests and integration tests, so what? I know that my app works as intended and those tests are useful to me, while some people have a perfect separation between their unit tests and integration tests, and yet their tests don't really test anything useful? My god, just relax and test what needs to be tested, and let's back down on the idea of 'You are doing tests wrong because this book said so' for a moment? It doesn't have to be as difficult as you are trying to make it look.
@RaMz00z
@RaMz00z 10 ай бұрын
While I agree with you on this particular video, I disagree on the sentiment. There is a proper way to do testing, and a wrong way. That's just a fact. Then again you can follow the rules and do useless testing, or not follow the rules and test useful stuff. The idea is to make test maintenable, performant, useful and not harmful. It is not a matter of "testing the proper behavior", it goes deeper than just that. If you're interested, go look at the theory of tests, it's really interesting.
@jeroen7362
@jeroen7362 10 ай бұрын
Totally agree, purism brings nothing good.
@molanlabe6543
@molanlabe6543 10 ай бұрын
A-freaking-MEN!!!!
@VladTheSlave
@VladTheSlave 10 ай бұрын
5:40 honest reaction to the number 69
@marcelasmar
@marcelasmar 10 ай бұрын
The title is a bit misleading, should have had “integration” instead of EF
@brettstech
@brettstech 10 ай бұрын
stopped as soon as he said in memory.
@zedmagdy
@zedmagdy 10 ай бұрын
but now ur CI/CD pipelines will be harder due to docker
@nickchapsas
@nickchapsas 10 ай бұрын
Nah they are extremely easy to implement. I've done it with TeamCity Docker-in-Docker in the past and it works like a charm.
@surgeon23
@surgeon23 10 ай бұрын
That was more obvious than I thought ¯\_(ツ)_/¯
10 ай бұрын
Aren't you writing tests now for EF Core instead of your app?
@nickchapsas
@nickchapsas 10 ай бұрын
Nop, I'm writing tests for my integrations and EF Core -> Database is part of them. This isn't unit testing.
@AkiraTTS
@AkiraTTS 10 ай бұрын
You could also use the Sqlite provider with an in memory sqlite connection, like: "Data Source=TestDb;Mode=Memory;Cache=Shared". It works like a real database and still remains in memory with no need for Docker.
@nickchapsas
@nickchapsas 10 ай бұрын
No you couldn't. ANY different provider than the one your app is actually using in production is wrong. It's not about being a real database but about being the EXACT database. Having SQLite and having InMemory is the same thing in terms of how useless it is.
@jameswilkinson8940
@jameswilkinson8940 10 ай бұрын
I'm curious, in the case of sqlite what kind of bugs could you miss with this approach as apposed to the real sqllite database with the exact same schema?
@nickchapsas
@nickchapsas 10 ай бұрын
@@jameswilkinson8940 Firstly, the schema wont' be the same. Postgres and SQLite (and any RDBMS really) has different field types in many cases so even the migrations generated for one won't be able to run on the other. You'll have to regenerate and run. That completely changes how your code is translated in SQL and how your code is executed on the db engine. Everything is different
@jameswilkinson8940
@jameswilkinson8940 10 ай бұрын
@nickchapsas I agree that the in memory database provider is very different to a real dB, but I think sqlites in memory database does not have the same limitations, as you literally build the schema in raw sql. I am using the same raw sql file that my encore entities were scaffolded from. I could be wrong, I just set this up yesterday so would be good to know if I am, but without an example I don't really understand, could you elaborate?
@steffbeckers
@steffbeckers 10 ай бұрын
​@@jameswilkinson8940 Some data types (DateTimeOffset, DateOnly, ...) are not supported in SQLite. I think a LINQ query which results in an APPLY operation in SQL is also not working on SQLite.
@7th_CAV_Trooper
@7th_CAV_Trooper 10 ай бұрын
Using EF at all is mistake. Lol
@hakari_
@hakari_ 10 ай бұрын
I use docker containers for my integration tests. There is a container for every test. Containers are automatically created and deleted by my code.
@jonathanperis3600
@jonathanperis3600 10 ай бұрын
"69, nice."
@FudgeYeahLinusLAN
@FudgeYeahLinusLAN 10 ай бұрын
Most common EF mistake is to use EF.
@jeroen7362
@jeroen7362 10 ай бұрын
Same question for you: What would you use instead? I love EF. Easy to work with icm Linq, perfect migrations, no more stored procedures, no more inline sql. all strong typed.
@FudgeYeahLinusLAN
@FudgeYeahLinusLAN 10 ай бұрын
@@jeroen7362 Dapper all the way.
@romanhrytskiv8845
@romanhrytskiv8845 10 ай бұрын
LOL that you even *have* to make a video on this 🤦🏻‍♂
@lucaslinhares4071
@lucaslinhares4071 10 ай бұрын
Extra virgen huh?
@opie0818
@opie0818 10 ай бұрын
The Domtrain ads ruined your channel, and sadly you've lost a subscriber.
@T___Brown
@T___Brown 10 ай бұрын
The biggest problem that devs make with EF is choosing to use EF. Incredibly slow and painful.
@jeroen7362
@jeroen7362 10 ай бұрын
What would you use instead? I love EF. Easy to work with icm Linq, perfect migrations, no more stored procedures, no more inline sql. all strong typed.
@EZman45
@EZman45 10 ай бұрын
69 nice
@parlor3115
@parlor3115 10 ай бұрын
First
@nickchapsas
@nickchapsas 10 ай бұрын
First
@JustinLampe
@JustinLampe 10 ай бұрын
FirstOrDefault()
@darkarmo
@darkarmo 10 ай бұрын
.TryToBeFirstOrBeLast()
@griffin123griffin
@griffin123griffin 10 ай бұрын
No, the main common mistake with Entity Framework is to use it . Not trolling at all 😅
@jeroen7362
@jeroen7362 10 ай бұрын
Same question for you: What would you use instead? I love EF. Easy to work with icm Linq, perfect migrations, no more stored procedures, no more inline sql. all strong typed.
@jeroen7362
@jeroen7362 10 ай бұрын
Right... ok guilty as charged but if i follow your drift. You fake your http client so you also are not having a full integration test. dealing with the network and http protocol would also be part of integration. consuming the message in the real client of your api would also need to be part of your integration test. So no, an integration test with mocks in it is not an full integration test. We run real integration test directly automated on the UI on a real environment with prepared test data. We have disabled "integration tests" in our unittest project that call services, and talk to real databases, we only use these while debugging and changing code. We run unittests/integration tests (if they do no need real api's etc) in the pipeline and some do use an in memory database because i do not want to test EF core, just like i do not want to test the http protocol. Ef core has been tested enough.
@nickchapsas
@nickchapsas 10 ай бұрын
The call to the service isn’t part of the integration, that would be part of the e2e test. However is you use a message bus then yes you should spin up a container for it
@jeroen7362
@jeroen7362 10 ай бұрын
@@nickchapsas The name integration means different things for different people. Also the scope can vary. Integration basically means that you put a thing in the mix and see if it works together with its neighbors and maybe the whole town. you could call it e2e. And it would be wise to focus on the neighbor that usually makes trouble. And that has never been EF core for me. I didnt mention servicebus but also for that we use in memory bus. Why would you test a servicebus? The bus would be covered enough in the automated UI testing (that is what i call integration test and you call it end 2 end) And the tester calls it regression test.
@josefromspace
@josefromspace 10 ай бұрын
@@jeroen7362 I'm not 100% sure if I agree with e2e for "between services", you could run e2e with Cypress and still miss on some important bugs that may or may not reflect on the UI, say for instance, you have a service called from a UI that incorrectly swallows the exception, it will seem as the UI has no issues, when in fact it does.
@dacke9000
@dacke9000 10 ай бұрын
This was good. Can you also do another video on how to properly mock the entity framework with something like NSubstitute? One of the issues that I ran into was trying to mock my response from a method on the DbSet. ex. dbContext.DbSetNotBackedByTable.FromSqlInterpolated($"SELECT Query");
@Simon-hw3um
@Simon-hw3um 10 ай бұрын
We did not do this, we have a real testing database. But we've recently started work to convert it all to using respawner and testcontainers. Mainly in the hope of it running faster. Will it? We have multiple DbContexts, and I hope to seperate our tests into multiple collections, allowing them to run simutaniously
@loop8946
@loop8946 10 ай бұрын
This reasoning was why your test container video was awesome for me. I knew there were differences and in my case it was obvious because I had to make separate migrations for the different database types and therefore it was a lot of work just to run tests. Using a test container feels like a proper integration test of live technologies instead of similar but not quite the same ones.
What Are Your Thoughts on Entity Framework Core vs. Dapper?
21:49
How IEnumerable can kill your performance in C#
11:02
Nick Chapsas
Рет қаралды 116 М.
小丑把天使丢游泳池里#short #angel #clown
00:15
Super Beauty team
Рет қаралды 46 МЛН
Schoolboy Runaway в реальной жизни🤣@onLI_gAmeS
00:31
МишАня
Рет қаралды 3,6 МЛН
Zombie Boy Saved My Life 💚
00:29
Alan Chikin Chow
Рет қаралды 20 МЛН
Brutally honest advice for new .NET Web Developers
7:19
Ed Andersen
Рет қаралды 151 М.
Entity Framework Core vs Dapper Performance in 2023
13:59
Nick Chapsas
Рет қаралды 95 М.
Don't throw exceptions in C#. Do this instead
18:13
Nick Chapsas
Рет қаралды 257 М.
The New Way of Calling Your Code in .NET 8 Is INSANE
12:34
Nick Chapsas
Рет қаралды 136 М.
Testing Entity Framework Core Correctly in .NET
8:03
Nick Chapsas
Рет қаралды 29 М.
The Logging Everyone Should Be Using in .NET
15:34
Nick Chapsas
Рет қаралды 60 М.
Turns out REST APIs weren't the answer (and that's OK!)
10:38
Dylan Beattie
Рет қаралды 148 М.
If Your Code Looks Like This... You're A GOOD Programmer
16:39
Continuous Delivery
Рет қаралды 62 М.
The New Way of Parsing ANY Type in .NET
13:03
Nick Chapsas
Рет қаралды 68 М.
Don't Use Polly in .NET Directly. Use this instead!
14:58
Nick Chapsas
Рет қаралды 57 М.
小丑把天使丢游泳池里#short #angel #clown
00:15
Super Beauty team
Рет қаралды 46 МЛН