0:00 - Intro 1:05 - Getting started: demo application code and setup 10:20 - Problems with testing methods that manipulates with external stuff (database edits, e-mail senders etc) 12:39 - Mocking explained 15:44 - Writing tests with mocking 18:05 - Adding references for testing with MOCK 20:51 - Using statement 22:12 - AutoMock.GetLoose() vs AutoMock.GetStrict(); 23:30 - Using AutoMock: Writing the Unit Test with mocking 35:06 - Refactoring method that's under a UnitTest 36:03 - Checking data: comparing two objects 40:19 - Testing method that returns void 48:16 - Testing SQl call modification 52:47 - Recap 53:30 - Advice for beginners 55:15 - What not to test and why 58:24 - Summary 59:27 - Learning steps 1:01:42 - Concluding remarks
Hey Tim, Great video as usual. There's absolutely no reason you should be getting any thumbs down. There are those who know how to code really well but don't know how to teach, but you can do both hands down. Thank you for giving back to the community.
Kind of. The tutorial is very good... if you're using AutoFac, or some kind of Dependency Injection. I'm modding a game, and need to mock some of the supplied API for testing offline. I understand what mocking is, but I don't use AutoFac. The first 18 minutes of the video were explaining the project architecture, the basics of unit tests, and the difference between tests that don't need mocking, and those that do. We then install Moq, and AutoFac.Extras.Moq. We then move on to only show the AutoFac features of Moq... not an overview of how to use Moq in its own right. If you don't use Dependency Injection, or you are just starting on the road to learning how to use a Mocking framework, this video doesn't teach you as the title says it will. This was the reason for my Thumbs Down... I felt that the title and thumbnail were misleading, compared to the content, regardless of how well that content was presented. This missed the first ten rungs of the ladder. For an introduction to Moq, it would be better to use Moq in isolation, and then teach AutoFac.Extras.Moq as a follow-on video, clearly stating ("With AutoFac") within the title and/or thumbnail of the video. I've been trying to follow along, but I don't have an AutoMock class, and Mock isn't IDisposable, so I can't scope it within a using block.
Have use Moq testing today, since we're starting to implement this framework within our product. Thanks to this video, it didn't take me long to create unit tests.
Most of the videos are time tagged by volunteer students. Scroll down in the comments to see who did it and give them a shout out! They certainly deserve it (Hint: Ralfs)
Tim, I really admire you the way you explain the things. I remember ignoring this lesson in 2018, but today I came back to the very same tutorial. Happy to learn from you Tim Thanks
Again you are coming in clutch! Another great video! I still find it quite hard to know how to use mocking in my tests I am supposed to write, but this definetly gave me a better idea about what mocking is, and now I mind be able to read the other tests and actually understand what is going on! Thank you!
even thou I use Nunit for testing, but this video helped me quite a bit. Thanks a lot. Yours are good, cause you not only show HOW - but you tell WHY. Pretty rare on youtube I say. Thanks again!
This is the kind of video that I'll never be able to finish watching. Kept falling asleep, then rewind back to watch again but fall asleep again. I've rewinded about four times this afternoon. 😂
when i first learnt abt tim i shared the same behavior you had. however, as time passes, i realize that i am using the wrong method. instead of watching the video, which is comprised of tons of new information, in a row, i should watch them bit by bit, namely 1. watch 5 more minutes 2. conclude what i have learnt 3. if i feel comfortable, go back to 1 4. otherwise, re-watch hope this helps
@@IAmTimCorey I have a question regarding mocking here for the LoadData method. Is it true that it's better to use object parameters instead of dynamic parameters because it creates issues in mocking? for example to use ___ LoadData(string sqlStatement, object parameter, string connectionStringName, bool isStoredProcedure = false) ___ instead of ___ LoadData(string sqlStatement, U parameter, string connectionStringName, bool isStoredProcedure = false)
Thank you so much for this clear and concise explanation.. I tried learning mocking from a book a year back but never understood it that time.. i thought I should give it a try one more time.. Now I Finally know what mocking is .. Thanks again..
I've been searching for a while a good content for tests in Microsoft environment and now I found a good explanation. Finally I understand the reason and how to test void and CRUD methods.
First: Thankyou for all your videos! I love them!, I am learning a lot thanks to them. Second: Does the base code that you use in the video belong to any of your published courses?
Hello Tim. Another good video. After digging, I found that Moq appears to be the industry standard for mock-ing (based on the nuget download count). So, even though the video is nearly 2 years old, the framework is still good to get familiar with.
Tim, this was a good video. I was a bit hesitant about mock frameworks as I am a firm believer in writing all code when it comes to unit test. That's the way I was taught in the 90's. I watched your video several times and then it clicked it my thought process on how you used moq framework and more importantly why. I had to think back on how I wrote all the extra code to test to realize how this can cut down on writing so much of it before being able to find bugs. Thanks for a great video, I do appreciate this and look forward to watching more.
Having watched your video on Unit tests yesterday; I started this video thinking how I missed the suspense of having to actually click run tests to get a green (or red) check mark. But man, the convenience enterprise provides is great! Will definitely have to look into those third party options for auto testing. Great video Tim, I know I'll be returning to watch again in the near future =]
Im also loving the live code coverage feature. Good to know about that too! You have helped me really much again. Tomorrow i will watch your vid about Autofac
Hi Tim! I have been a big fan for a long time. Always recomend your videos to my friends. A year ago I switched jobs and now I am working with Spring Boot instead of C#. And right now we are debating using H2 as a in memory database for testing. I would love to hear your thoughts about it. I always heard you should not use a database for testing, but at the same time is nice to know that our repositories are working and the db contrains are working as well. Thanks in advance!
Thank you for the amazing content, Tim. I have been following you for quite some time and I always learn a few things from your videos even when they cover topics that I am already familiar with. Just wondering what your thoughts are on Test Driven Development. Is it something that you practice in the projects that you work on? I am looking to learn more about it. I would be most grateful if you can cover it in a video sometime. Thanks again. :)
One thing I might ask you Tim, at 47.00 You're talking about how to test the VOID methods, but the explanation you gave was about just calling the void method 'certain number of times' not exactly the void function execution / catching at test-phase
In order to test more than just that the method fired, the method has to change something that you can test. Unit testing is about testing effects. So, you need to find an effect to evaluate.
Hey Tim, great content as always. I was hoping to find a full unit test course on your site! I'd be a day-1 customer if you manage to put one together. In any case, I was hoping you might be able to help with some simple guidance if you don't mind. I understand mocking within the context of unit tests, but I'm wanting to mock service calls for my ViewModels that ultimately the UI binds to. Basically, I have a ViewModel that makes a service call, which hits a database and (for example) returns a list of people, in my view I have a DataGrid that binds to the results in the ViewModel. No problem. What I want to do is instead of hitting the actual database I'd like to return mocked objects. I have cobbled something together manually that handles this, but can you shine some light on best practices with this type of scenario? Basically what I'm doing now is I have a dummy service (both the dummy and actual service implement the same interface) and the dummy service (manually) mocks up service calls and results. I'm using dependency injection to determine which service I'm actually going to use. Does this sound like a decent approach? Any guidance is greatly appreciated!
In my project I use Moq/Xunit and Dapper/DynamicParameters... If I don't use DynamicParameters my test works, but if I use DynamicParameters, my mock object just returns null??? If I just rund the code with DynamicParameters everything works fine and I get data back from my test DB Do you know a workaround to solve the problem with Dapper/DynamicParameters in unit testing?
This work for me. mockdb.Setup(x => x.DbQueryAsync( "USP_S_Test_Get", CommandType.StoredProcedure, It.IsAny())) .Returns(GetTestIEnum()); var cls = mock.Create(); var actual = cls.Get(testCode);
for some reason I thought mock tests were something more closely resembling integrated tests but I was wrong I feel like this is not the best way to test things related to database, which just enforces you to check your input twice instead of actually checking the output for complex enough queries, it pains me to say but I guess I'll just have to stick to the real thing in docker with proper setup and teardown of tests
Hey, Tim. I'll be testing this in a personal project I have in development. But first I need to know something about the connection string best practices... In a scenario like the one you show, where would you put it? In the UI project or in the library itself? I understand you're using Sqlite so I guess it kind of maps itself (?). Never used it as I prefer to have an actual database, whenever possible. My point is... I created an appsettings.json on a consoleUI, where I'm testing the actual inserts to the database to check if they're working correctly. And in the library on getting the connection string. I know I should have both on one side only, but which side? It makes sense to me to have them in the library, but I think I've read somewhere we shouldn't do that, for some reason... I need to know, from your experience, what's your take on this?
We store the connection strings in the appsettings.json file (or app.config/web.config if you are on .NET Framework). Those files are associated with front-end project types (Console, WinForm, WPF, ASP.NET Core, etc.) We put the connection string in the front-end because then the front-end dictates the database that the library will use. This is useful because we can reuse the library in multiple projects with different database locations (even if it is the same database structure it will live in different locations).
@@IAmTimCorey that was my thought. But then there's the case that someone that will implement another UI forgets about connection string setup for some reason or names it differently. Anything we can do about that aside from just letting it throw an exception? Or is it better to just let it blow up?
Uuuh, dumb question: how have you written those test classes? Also 13:55 what if you want to actually test the DB interractions? :P 34:44 I don't get it, we are mocking the data returrn by the sql method, why changing the sql string parameter fails the test? Seems like a neat framework though. :P
OK, I'm going to answer your questions in the order you asked: 1. I wrote those test classes by hand. No special tool needed. 2. If you want to test DB interactions, that is no longer a unit test. That is an integration test and it is a more complex animal. 3. Changing the SQL string means that the call was no longer made that we expected to be made. If you expect someone to call an "Add" method and pass in a 1 and a 3 as parameters, that isn't the same call as passing in a 2 and a 4. The same is true for this. If the SQL string isn't the same, it won't return the same results that we expect.
thanks for the great video, as always what do you do if you want to test a class that doesn't implement an API? do you have to "force" it into implementing one?
Is Moq a good choice for mocking integration tests? For example, if a method calls two methods: 1) read a mocked thermometer and returns the value and then 2) the value is checked against limits and returns a bool value.
It sounds like you are doing unit testing there, not integration testing. Integration testing is usually about testing the interaction of multiple things. You can still use moq for it if you want to put a boundary around the test, though.
Hi Tim, Thanks a lot for such a wonderful video. I appreciate your advices and sharing with us how you work (for example how far do you go with test coverage). Is there any tool/platform that you would recommend for analysing test coverage, code smells, etc (i.e. sonarqube)?
Hey Tim!! any chance you can update this video to the latest version of Moq?, this one aged really bad, right now Moq is not required to use "using". Thanks!
This was of great help for my project, Thanks Corey! By the way, how would you setup your LoadPeople call if you are using LoadData multiple times with different querystrings within LoadPeople (let's assume thats a valid use case)
I'm going to do a video on it, hopefully tomorrow. The bottom line is this: the implementation wasn't great, but the people complaining are WAY more in the wrong than the creator. He asked for help, got nothing, and so he tried to get help on his own. He didn't think through all of the implications, so it wasn't the perfect solution. However, he listened and removed the problematic code immediately. Open source for free is not sustainable. We need better solutions to make sure these creators are compensated so that they can maintain the things that the whole world relies on.
53:43 Thank you. Shelf it is. Somewhere in the SOLID series I kinda started to lose a grip on my understanding of things. Interfaces and abstraction was ok, but autofac threw me off. For beginner, this feels, like it should be on some sort of "Master level" not "Advanced topics" playlist... Then again, it's most likely just because of lack for trying things out :)
11:51 - "You have to have the same schema for production & testing databases" & "You always need to clean up your testing database" - well yeah, that's how I program on Ruby on Rails. Takes just installing one plugin. Mocking your database is the worst thing you can do in Testing. Mocking is used to mock things that change from run to run (e.g. requests to a remote server, Time.Now() request, probably some other things). 13:17 - There's nothing wrong with having a hundred dependencies if they all make you able to deploy your features faster and with higher quality. Why reinvent the wheel if someone made a plugin? Maintenance of incompatibility between plugins is not as bad as reinventing say a State Machine library in every project.
I can see how having hundreds of dependencies could be considered fine, but you really want a bit more simplicity per class. This comes back to the Single Responsibility Principle. If you have hundreds of dependencies (I know you were exaggerating, I'm just using that same language) then your class/method is probably doing too much. For example, if a method has a dependency on HTTPClient and IDataAccess, that's probably too much. Talking to the web and talking to the database is probably a violation of SRP. Add in an IEmailClient and a ISmsClient and now you are doing way too much in one method. At that point, you aren't doing unit testing, you are doing integration testing.
Hi Tim, I am trying to combine the mocking with many other areas. But get a little stuck. In one of your other videos you have a line with something like: var x = await _sqlDataAccess.LoadData(usp, new { LanguageID = LanguageId }); This is kind of a combination of my classes with your logic. It looks like that dynamic is not supported by moq and xunit. With I replace it here with a single int it works. But that brings too much restrictions to use this line for other options. So, I thought to replace it with a List but then again it doesn't work. I am doing debug test and at the time it should give me back a result from the Mock it shows Null. Also I was thinking if I bring the parameter maybe as a tuple into the dataAccess class and convert it there to an List
I believe it should support dynamic but if it doesn't, you can always create your own mock manually of the sqlDataAccess class. Just create your own class that implements the interface and put your mocked code in the methods.
When we passed in our known values, we knew what the resulting SQL string should look like. When it did not look the way we expected, we knew we had an issue. It compared the two strings to be sure they were the same. They weren't. Therefore, our expectations did not match our code's reality.
Hello Sir , thank you for all tutorials. Also , if you can make intermediate Web api project from scratch, it would be perfect for us. ( I finished your Web api tutorial and it was awesome. That's why I wanted one more full project :) ) Thank you again for your all videos Sir.
I have been learning so many things from you through years and used them in my projects. I appreciate your hard work. You have a great way of explaining everything; however, just as my personal opinion, you repeat the same thing in many ways that may waste time. I am waiting to see how you mock the database for a while and you are explaining how mock is spelled, repeating why _database is needed a few times, etc.
I am using the IDataAccess (DataLibrary) you made in another video, but I got a System.NullReferenceException on the actual list in the unit test. How does the unit test (especially the setup) look like if using the DataLibrary from your video "Connecting C# To MySQL Using Blazor"? I am not directly returning the output, but putting it in a global list and return it in a getter method.
thanks for theexcellent video. Can you please tell me how to test a data layer function which calls stored procedure? Your eg shows simple queries but how do i test a function which calls SP
@@IAmTimCorey cool..but am little confused because how do i mock command object. Eg IDbCommand command = GetCommand(con)) {command.comandText="someSPName"}.
Hi Tim, If you are bypassing the code of SQLLiteDataAccess class than why do we need the moq library for mocking. We can simply have two classes implementing ISQLDataAccess where one would return the actual data from DB and the other mock class will return the mock data. So we can create our app context at the starting of our app where all the interfaces would have the actual data access classes and from the testing project the context interfaces will have the mock classes Here using moq requires lot of code to be written as well as adding a library in your project Correct me if I'm wrong
What you are proposing is to write a class to mock the implementation. That is what Moq does for you in a more dynamic manner. It allows you to make a simple mock (you don't have to mock everything, just what you are using) and it allows you to change the output values to test various scenarios (something your actual implementation would have a harder time doing).
@@IAmTimCorey Hi Tim, We can also achieve testing different scenarios using mock classes and return the output on the basis of some reference IDs. By using mock classes all the mock return code would be in mock classes and our unit test functions would have just assertion code. In moq we need to write objects of moq classes than use create setup functions All these code isn't required. I have implemented the mock classes in my company although I can't share the code but I will write some short demo code and will present that to you in sometime.
With moq you can configure it to return different data for different scenarios. Therefore there is greater flexibility than if you hardcoded a result into a class and you won’t end up with loads of classes you have created to use in a single test. Having said that I do use a fake class in many cases when I just need an instance and I am not testing it.
Great video Tim thanks. Never really done any unit testing as the firms I've work at don't seem to do them, so never really got into them. AutoFac... Looks like I missed a video - DI With AutoFac - YT seems to think I've watched it. I'll have to go and watch that now as I had no idea what AutoFac is.
Hi Tim, love your videos. I am a junior - mid level software engineer trying to bring some implementation tests to my company. We use entity framework with a database for each of our clients where each DB has the same table structure (same tables and columns within those tables across all dbs). Do you have any suggestions on what framework/Design pattern to use to achieve this?
Sorry, I'm not sure I understand. Are you saying you want to do implementation testing on your clients' installations? If so, that sounds like something you want to build custom since it is post-deployment.
Awesome video but I didn’t got a grasp of one important thing. Almost always I am using stored procedures for Dapper. Should I put sql syntax into my tests directly only for the sake of testing or Moq somehow is learning about stored procedures existing in the database? Don’t understand how to test repository in my application which contains tons of different stored procedures. Sorry if my question was a bit clunky and demonstrates my utter ignorance.
Personally, I don't unit test my stored procedures. They don't have logic in them almost ever beyond the filtering and sorting of data. That means I don't need to have SQL in my unit tests in C# because I'm not testing the results of the queries. Instead, I can mock the results so that I can test my actual C# code.
When you have a large number of classes that are injected in the class that you want to test. Is that a sign that it's a method that you shouldn't test because it might be too large? Or can I test them anyway. My question is really if you have like repo, Service and controller setup in your API should you test Services ? Service often has more business logic and do you test business logic with Unit test.
@@IAmTimCorey Thanks for the reply, it might be obvious to test everything but starting testing a large project without tests is a bit much to chew in.
Hi Tim Corey, Hope you're doing well. I watched your all video series it help me alot in real time. I'm struggling for writing unit test using xunit framework. One for the method is inserting records into SQL db. I have written unit test case for this method but in the end cmd. executenonquery throwing exception like below "BeginExecuteNonQuery requires an open and available connection. The connection currently state is closed" I believe I need to mock sqlconnection any suggestions from your end. Appreciated
The first step is to identify what logic you are trying to test. Are you testing that the insert method is called or are you trying to test that the record was inserted? Unless your insert method is performing some logic, it does not need to be tested. If it is doing some logic on the inserted data, separate that logic from the actual insert (single responsibility principle) and then test just the logic method.
@@IAmTimCorey great to here thank you for your quick response, I'm trying to test valid/invalid dummy data inserting into db but without hitting db it's should work till now no luck. I think I'm not sure I need to add config file into my test project and then i need to mock it. Please suggest is that right way I'm think? Again Appreciated..!
I always feel like I'm close to understanding the purpose of mocking. But I never really get there by watching videos. The examples I see is basically just tests to see if hard coded values matches other hardcoded values. It feels like we are not really getting a unit-test but more a new kind of interface thats ment for parameters and return values. Since the Mocks I have seen so far is saying "this is what this function needs to do. Every time. It needs to have this parameter or maybe this return value". But if its that static why dont we just use normal Asserts for this without Mocks since the mocked values are hardcoded in the end. Maybe its just because beginner examples are not complex enough. But it would be interesting to see a example of where a mock-test actually secures code. Getting a failed test every time a method returns something else or uses a different param then a specific case seams kind of.. troublesome.
The purpose behind mocking is to remove that item as a dependency. We aren't testing that item, we are testing the method that uses that item. That's why we set it to return a known value every time. We want to test what happens when that value comes back to them method. We can control the inputs in order to test how they are used.
You should test one thing per test but you can have multiple asserts if you have more than one thing to check. No reason to write four tests to test the exact same thing just so you can assert on different parts.
I love the stuff with Moq, but due to the fact that extension methods are not supported, when you want to mock the ILogger it becomes a real mess (LogDebug, LogInformation are extension methods) :( You can only use the plain Log method, which is quite impractical. What is your opinion on this?
Awesome video. Can you please help with ADO.Net + Repository pattern + Unit testing in .Net core? Only quick sample is enough. I am facing issues with mocking stored proc and proper repository arrangements. Thanks.
I wanted to ask how to go about applying testing to following scenario in following .NET Core App: Class A is a Background service that consumes a message from a Rabbit queue. Class B is a "MessageProcessor" class. It has a public method. This method makes a call to a private method that invokes a public method of Class C. So Class B has a dependency on Class C. Class C is a class that makes REST API call to an external API. Do I have to put all 3 classes under separate tests or does it depend on what to test/what I should be testing? So if I wanted to test the behaviour of processing a message I would put Class B under test and mock it's dependencies appropriately. My current understanding is that I should be testing specific behaviour. Is that right?
Hey Tim, love your videos.. I like how you explain things. One question, my project test doesn't run at all. It does spin but at the end it just says something like "0 tests ran, 0 tests failed, 0 tests skipped." Also, the test says "Excluded from Live Unit Tests" and I'm right-clicking and choosing "Include...." doesn't seem to have an effect. Thanks!
What do you do if your public method you're testing calls a private method that gets data from a db? How do you mock the private method so you can return fake data?
I don't mock private methods. I rework the dependencies. It sounds like you have a dependency (data access) that is not easily replaceable. That is something to work on fixing. Doing so will not only make your unit testing easier, it will also lead to a better design.
@@IAmTimCorey Hmm, so we have a Data Access Layer and inject the dataContext into the class. I really like your idea, but I'm not entirely certain of how I could go about refactoring this. We are using the repository pattern and have a controller calling a repo's public method (which is what I want to test). In that public method we have a private method that takes an id, joins 3 tables together, and returns some information. The public method then uses that information for more calculations. So what would that look like, or how would you go about implementing what you mentioned? Do you have a video that talks about this? We are using dotnet core 3.1 if that helps.
@@IAmTimCorey Ok, I will try to move that out. If I move that piece out of the repository method, but I still have a private method that does some calculations with that data, should I move that to the DAL folder as well or keep it private?
HI Tim, Very informative , this will help me in some way. I am facing some issue in mocking like I have created one integration Test based on CRUD operation but it was talking to real data ..how to mock this integration test (mock request response to create data and than update and delete it.
Hi!, Great videos about testisng. One question, do you have any video to learn how to effectively moq Entitify framework DbContext and DbSet that can be seen as Unit of work and Repository pattern? Perhaps it is better in this case to use a real database in memory like localdb, memorydb o sqlite on memory?
As Tim said, it is difficult if not impossible to directly mock EF native classes. What I have done before is abstract/wrap all of EF, so that in business logic we never reference any EF objects/types directly. Instead all access is done through our own wrapping interfaces and class implementations that contain all our CRUD business logic etc. Then all of these interfaces and types can be injected as per usual, and then easily tested and mocked etc. For example: // Generic base interface to represent a repository/set of any entity type T. Also supports IEnumerable, IQueryable etc. interface IRepository : IEnumerable, IQueryable { IEnumerable GetAll(); T GetById(int id); T Add(T new); T Update(T changed); void Delete(T); void Delete(int id); // Etc... } // Generic base implementation of the Repository interface using EF DbSet (in a DbContext). Again generic type T is an entity type. public abstract class Repository : IRepository { protected readonly DbSet _dbSet; public Repository(DbSet dbSet) { _dbSet = dbSet; } // Includes base implementation for IQueryable & IEnumerable; most else abstract. .... } // Example of specific repository interface for a repository/set of Persons, and extends the generic interface above. interface IPersonRepository : IRepository { ... void MyCustomMethod(); ... } // Can also add extra custom methods here // Example of specific class implementation of a repository/set of Persons using EF DbSet (in a DbContext). public class PersonRepository : Repository, IPersonRepository { public PersonRepository(DbSet dbSet) : base(dbSet) { } //...etc public Person GetById(int id) { return _dbSet.FirstOrDefault(x => x.Id == id); } //...etc public void MyCustomMethod() { /*Does Something*/ }; //... } // IDataContext interface with a get property for every repository/set class for each type of entity. interface IDataContext { //... IPersonRepository Persons { get; } //... all other repository/entity types... } // Implementation of IDataContext using EF DbContext and EF DbSets etc. All repository/set properties use lazy init. public class EFDataContext : IDataContext { private DbContext _dbContext; // Can inject EF DbContext or instantiate in ctor etc. //... public virtual IPersonRepository Persons { get { if (_persons == null) _persons = new PersonRepository(_dbContext.Persons); // Lazy init with EF DbSet. return _persons; } } private IPersonRepository _persons; // Field for lazy init. // Repeat pattern for for all entity types... } We did nearly of this using code-generation from EF T4 templates, similar to how EF POCO entity data model classes are created out of the box. We extensively modified these T4 templates to also create/update all the extra interfaces and repository classes, which is absolutely necessary for 200+ entity types. But if you only have a few entity types this could be done by hand fairly quickly. You would probably also want to make use of partial classes, so you can code-gen half the Repository into one Obviously the code in the EFDataContext class cannot be unit tested, but it doesn't need to be since it is code-generated. Then you can pass/use only IDataContext and IPersonRepository (etc) in your business logic, all of which can be easily mocked and tested. Also then you can entirely swap out EF with a different ORM if you wanted to as well, since we've basically created a generic ORM interface. However the code generation (in our case) was coupled with the EF code gen and the EF EDMX model etc.
0:00 - Intro
1:05 - Getting started: demo application code and setup
10:20 - Problems with testing methods that manipulates with external stuff (database edits, e-mail senders etc)
12:39 - Mocking explained
15:44 - Writing tests with mocking
18:05 - Adding references for testing with MOCK
20:51 - Using statement
22:12 - AutoMock.GetLoose() vs AutoMock.GetStrict();
23:30 - Using AutoMock: Writing the Unit Test with mocking
35:06 - Refactoring method that's under a UnitTest
36:03 - Checking data: comparing two objects
40:19 - Testing method that returns void
48:16 - Testing SQl call modification
52:47 - Recap
53:30 - Advice for beginners
55:15 - What not to test and why
58:24 - Summary
59:27 - Learning steps
1:01:42 - Concluding remarks
Thank you! I have added it to the video.
Hey Tim,
Great video as usual. There's absolutely no reason you should be getting any thumbs down. There are those who know how to code really well but don't know how to teach, but you can do both hands down.
Thank you for giving back to the community.
I appreciate the kind words.
Kind of. The tutorial is very good... if you're using AutoFac, or some kind of Dependency Injection.
I'm modding a game, and need to mock some of the supplied API for testing offline. I understand what mocking is, but I don't use AutoFac. The first 18 minutes of the video were explaining the project architecture, the basics of unit tests, and the difference between tests that don't need mocking, and those that do. We then install Moq, and AutoFac.Extras.Moq. We then move on to only show the AutoFac features of Moq... not an overview of how to use Moq in its own right.
If you don't use Dependency Injection, or you are just starting on the road to learning how to use a Mocking framework, this video doesn't teach you as the title says it will. This was the reason for my Thumbs Down... I felt that the title and thumbnail were misleading, compared to the content, regardless of how well that content was presented. This missed the first ten rungs of the ladder. For an introduction to Moq, it would be better to use Moq in isolation, and then teach AutoFac.Extras.Moq as a follow-on video, clearly stating ("With AutoFac") within the title and/or thumbnail of the video.
I've been trying to follow along, but I don't have an AutoMock class, and Mock isn't IDisposable, so I can't scope it within a using block.
Thanks for making a complicated subject easy to understand. You have a real talent for teaching!
Thank you.
Have use Moq testing today, since we're starting to implement this framework within our product. Thanks to this video, it didn't take me long to create unit tests.
Excellent! I am glad it was helpful.
It had been a while since I finished watching a video with the excitement of having just learned something new and empowering. Thank you.
You are welcome.
I really like how your videos are segmented so that I can jump to a particular area by hovering over the progress bar.
Most of the videos are time tagged by volunteer students. Scroll down in the comments to see who did it and give them a shout out! They certainly deserve it (Hint: Ralfs)
Tim, I really admire you the way you explain the things. I remember ignoring this lesson in 2018, but today I came back to the very same tutorial. Happy to learn from you Tim Thanks
You are very welcome! I like to hear about students being able to search the channel and find just what they need when they need it.
Damn you Tim You videos are amazing and so addictive , it's 4 AM here and i have work tomorrow. Thanks a lot for sharing you knowledge.
I'm glad you are enjoying them. Hopefully, you don't curse my name when you are at work.
Again you are coming in clutch! Another great video! I still find it quite hard to know how to use mocking in my tests I am supposed to write, but this definetly gave me a better idea about what mocking is, and now I mind be able to read the other tests and actually understand what is going on! Thank you!
Happy to help!
I've watched 2 or 3 other training videos on this topic, and yours clears it up for me. Thanks!
I am glad it was helpful.
even thou I use Nunit for testing, but this video helped me quite a bit. Thanks a lot. Yours are good, cause you not only show HOW - but you tell WHY. Pretty rare on youtube I say. Thanks again!
You are welcome.
Beautifully explained with calm voice. So good!
Thanks for trusting Tim for your learning
This is the kind of video that I'll never be able to finish watching. Kept falling asleep, then rewind back to watch again but fall asleep again. I've rewinded about four times this afternoon. 😂
Watch it at night so you at least get a good night’s sleep out of it.
@@IAmTimCorey 😄😄😄😄
when i first learnt abt tim i shared the same behavior you had. however, as time passes, i realize that i am using the wrong method. instead of watching the video, which is comprised of tons of new information, in a row, i should watch them bit by bit, namely
1. watch 5 more minutes
2. conclude what i have learnt
3. if i feel comfortable, go back to 1
4. otherwise, re-watch
hope this helps
That means you do not give up easily- that’s good
Story of my life. I go to a beach 🏝️ or mountain 🏔️ shopping center it’s not easy but his vids are the best
Thank you so much for all your videos I can't stress enough the amount of gratitude I, and I'm sure the rest of us, have for you, so truly thank you.
You are welcome.
@@IAmTimCorey I have a question regarding mocking here for the LoadData method.
Is it true that it's better to use object parameters instead of dynamic parameters because it creates issues in mocking?
for example to use
___
LoadData(string sqlStatement, object parameter, string connectionStringName, bool isStoredProcedure = false)
___
instead of
___
LoadData(string sqlStatement, U parameter, string connectionStringName, bool isStoredProcedure = false)
Thank you so much for this clear and concise explanation..
I tried learning mocking from a book a year back but never understood it that time.. i thought I should give it a try one more time..
Now I Finally know what mocking is ..
Thanks again..
Happy to help
Thanks for showing me a whole new world, shining, shimmering, splendid...
You are welcome.
Thank you!!! Great tutorial on Mocking!!! Got the first of many written. Awesome!!!
You are welcome.
I've been searching for a while a good content for tests in Microsoft environment and now I found a good explanation. Finally I understand the reason and how to test void and CRUD methods.
Excellent!
I'm always thankful for your efforts.
You are welcome.
You the man TIm! My go 2 for C# learning. Cheers
Thank you!
Thanks, Tim!
Always good value content!
You are welcome.
Awesome tutorial !! Thank you once again for sharing this Tim.
You are most welcome. Thanks for watching.
Great video. Very addictive channel.
Thank you!
First: Thankyou for all your videos! I love them!, I am learning a lot thanks to them.
Second: Does the base code that you use in the video belong to any of your published courses?
No, it does not.
Hello Tim. Another good video. After digging, I found that Moq appears to be the industry standard for mock-ing (based on the nuget download count). So, even though the video is nearly 2 years old, the framework is still good to get familiar with.
Yep, it is a pretty popular framework.
Thanks Tim! .. from Neuquén Argentina. It is a very good and illustrative video.
You are welcome.
Tim, this was a good video. I was a bit hesitant about mock frameworks as I am a firm believer in writing all code when it comes to unit test. That's the way I was taught in the 90's. I watched your video several times and then it clicked it my thought process on how you used moq framework and more importantly why. I had to think back on how I wrote all the extra code to test to realize how this can cut down on writing so much of it before being able to find bugs. Thanks for a great video, I do appreciate this and look forward to watching more.
Awesome! I'm glad the video was able to help clarify somethings for you and improve your process.
Having watched your video on Unit tests yesterday; I started this video thinking how I missed the suspense of having to actually click run tests to get a green (or red) check mark. But man, the convenience enterprise provides is great! Will definitely have to look into those third party options for auto testing.
Great video Tim, I know I'll be returning to watch again in the near future =]
Excellent!
Thank you for showing the code behind the class SqlLiteDataAccess at 55:30. Wow, Dapper is awesome! Great Video!
I definitely agree that Dapper is awesome. I'm glad you enjoyed the video.
Dapper supports async fully so I would recommend making your class async as well.
Im also loving the live code coverage feature. Good to know about that too! You have helped me really much again. Tomorrow i will watch your vid about Autofac
Great!
Always top notch.
Thanks
This is fantastic. Extremely relevant to what I am currently working on. Thank you!
I'm glad it is so relevant to you. Thanks for letting me know.
I really needed to refresh this today. Thanks you. and keep it up!
Good Explaining!
Excellent! Glad I could help.
Tim, thanks for the effort. Well done.
Thank you!
Thanks man! Yet another great tutorial. I get more and more Inout for my new project!
Cool!
Really good video. Thanks for making it easy, Tim!
You are welcome.
Great video Tim
Thanks!
Very informative! Thank you for all the effort, I'm sure, went into making this video!
You are welcome.
great video, thanks a lot Tim
Glad you enjoyed it
You saved my life once again :)
Good to know.
Thank you Tim you are helping me a lot.
You are very welcome
I loved this video! Thanks again Tim
You are welcome.
Hi Tim! I have been a big fan for a long time. Always recomend your videos to my friends.
A year ago I switched jobs and now I am working with Spring Boot instead of C#. And right now we are debating using H2 as a in memory database for testing.
I would love to hear your thoughts about it. I always heard you should not use a database for testing, but at the same time is nice to know that our repositories are working and the db contrains are working as well.
Thanks in advance!
I appreciate you Tim!
Thank you!
Thanks sir for this great video.
You are welcome.
I really like your advice, and autofac is so nice. Not have to click run every time you update your code is so convenient. Thank you for the content.
You are welcome.
Thank you for the amazing content, Tim. I have been following you for quite some time and I always learn a few things from your videos even when they cover topics that I am already familiar with. Just wondering what your thoughts are on Test Driven Development. Is it something that you practice in the projects that you work on? I am looking to learn more about it. I would be most grateful if you can cover it in a video sometime. Thanks again. :)
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
Amazing course
Thanks!
Thanks tim for more new stuff
You are welcome.
One thing I might ask you Tim, at 47.00 You're talking about how to test the VOID methods, but the explanation you gave was about just calling the void method 'certain number of times' not exactly the void function execution / catching at test-phase
In order to test more than just that the method fired, the method has to change something that you can test. Unit testing is about testing effects. So, you need to find an effect to evaluate.
Hey Tim, great content as always. I was hoping to find a full unit test course on your site! I'd be a day-1 customer if you manage to put one together.
In any case, I was hoping you might be able to help with some simple guidance if you don't mind.
I understand mocking within the context of unit tests, but I'm wanting to mock service calls for my ViewModels that ultimately the UI binds to. Basically, I have a ViewModel that makes a service call, which hits a database and (for example) returns a list of people, in my view I have a DataGrid that binds to the results in the ViewModel. No problem. What I want to do is instead of hitting the actual database I'd like to return mocked objects.
I have cobbled something together manually that handles this, but can you shine some light on best practices with this type of scenario? Basically what I'm doing now is I have a dummy service (both the dummy and actual service implement the same interface) and the dummy service (manually) mocks up service calls and results. I'm using dependency injection to determine which service I'm actually going to use.
Does this sound like a decent approach? Any guidance is greatly appreciated!
Yep, that works. You can use Moq to make the dummy service though.
In my project I use Moq/Xunit and Dapper/DynamicParameters...
If I don't use DynamicParameters my test works, but if I use DynamicParameters, my mock object just returns null???
If I just rund the code with DynamicParameters everything works fine and I get data back from my test DB
Do you know a workaround to solve the problem with Dapper/DynamicParameters in unit testing?
This work for me.
mockdb.Setup(x => x.DbQueryAsync(
"USP_S_Test_Get",
CommandType.StoredProcedure,
It.IsAny()))
.Returns(GetTestIEnum());
var cls = mock.Create();
var actual = cls.Get(testCode);
for some reason I thought mock tests were something more closely resembling integrated tests but I was wrong
I feel like this is not the best way to test things related to database, which just enforces you to check your input twice instead of actually checking the output
for complex enough queries, it pains me to say but I guess I'll just have to stick to the real thing in docker with proper setup and teardown of tests
Thanks for watching
Hey, Tim.
I'll be testing this in a personal project I have in development.
But first I need to know something about the connection string best practices...
In a scenario like the one you show, where would you put it? In the UI project or in the library itself?
I understand you're using Sqlite so I guess it kind of maps itself (?). Never used it as I prefer to have an actual database, whenever possible.
My point is... I created an appsettings.json on a consoleUI, where I'm testing the actual inserts to the database to check if they're working correctly.
And in the library on getting the connection string. I know I should have both on one side only, but which side?
It makes sense to me to have them in the library, but I think I've read somewhere we shouldn't do that, for some reason...
I need to know, from your experience, what's your take on this?
We store the connection strings in the appsettings.json file (or app.config/web.config if you are on .NET Framework). Those files are associated with front-end project types (Console, WinForm, WPF, ASP.NET Core, etc.) We put the connection string in the front-end because then the front-end dictates the database that the library will use. This is useful because we can reuse the library in multiple projects with different database locations (even if it is the same database structure it will live in different locations).
@@IAmTimCorey that was my thought.
But then there's the case that someone that will implement another UI forgets about connection string setup for some reason or names it differently.
Anything we can do about that aside from just letting it throw an exception? Or is it better to just let it blow up?
Another great tutorial!!
Thanks!
Uuuh, dumb question: how have you written those test classes?
Also 13:55 what if you want to actually test the DB interractions? :P
34:44 I don't get it, we are mocking the data returrn by the sql method, why changing the sql string parameter fails the test?
Seems like a neat framework though. :P
OK, I'm going to answer your questions in the order you asked:
1. I wrote those test classes by hand. No special tool needed.
2. If you want to test DB interactions, that is no longer a unit test. That is an integration test and it is a more complex animal.
3. Changing the SQL string means that the call was no longer made that we expected to be made. If you expect someone to call an "Add" method and pass in a 1 and a 3 as parameters, that isn't the same call as passing in a 2 and a 4. The same is true for this. If the SQL string isn't the same, it won't return the same results that we expect.
1 and 2, ok!
Still not sure about how this system interact related to 3 but that's more like about the tool used.
Thanks for your time.
really good video, as always!!!
Thanks!
thanks for the great video, as always
what do you do if you want to test a class that doesn't implement an API?
do you have to "force" it into implementing one?
Is Moq a good choice for mocking integration tests? For example, if a method calls two methods: 1) read a mocked thermometer and returns the value and then 2) the value is checked against limits and returns a bool value.
It sounds like you are doing unit testing there, not integration testing. Integration testing is usually about testing the interaction of multiple things. You can still use moq for it if you want to put a boundary around the test, though.
Hi Tim,
Thanks a lot for such a wonderful video. I appreciate your advices and sharing with us how you work (for example how far do you go with test coverage). Is there any tool/platform that you would recommend for analysing test coverage, code smells, etc (i.e. sonarqube)?
I don't really have a tool beyond what Visual Studio provides. They have some great features for test coverage, test running, etc.
Hey Tim!! any chance you can update this video to the latest version of Moq?, this one aged really bad, right now Moq is not required to use "using". Thanks!
Thanks for the suggestion. Please add it to the list on the suggestion site so others can vote on it as well: suggestions.iamtimcorey.com/
@@IAmTimCorey Done!
This was of great help for my project, Thanks Corey! By the way, how would you setup your LoadPeople call if you are using LoadData multiple times with different querystrings within LoadPeople (let's assume thats a valid use case)
qq for initial set up for mocking & xunit i have got the error " response status code does not indicate success: 403(Forbidden).
That's a permission issue (a 403 error).
Hi Tim! Whats your opinion of Moq's latest updates?
I'm going to do a video on it, hopefully tomorrow. The bottom line is this: the implementation wasn't great, but the people complaining are WAY more in the wrong than the creator. He asked for help, got nothing, and so he tried to get help on his own. He didn't think through all of the implications, so it wasn't the perfect solution. However, he listened and removed the problematic code immediately. Open source for free is not sustainable. We need better solutions to make sure these creators are compensated so that they can maintain the things that the whole world relies on.
@@IAmTimCorey Great response thanks! Looking forward to the video.
I second that@@IAmTimCorey
Thanks Tim.
You are welcome.
Interesting video Tim, I am curious first can you moq without dependency injection, specific for extension which is based of WPF.
That is harder to do, since it is a hard dependency.
53:43
Thank you. Shelf it is. Somewhere in the SOLID series I kinda started to lose a grip on my understanding of things.
Interfaces and abstraction was ok, but autofac threw me off.
For beginner, this feels, like it should be on some sort of "Master level" not "Advanced topics" playlist... Then again, it's most likely just because of lack for trying things out :)
Yep, it takes a bit of work to get to this point for sure.
Thanks for adding times to the descriptions... I am sure you will understand how autofac in a few days, didnt take me too long
@@bigdummyhead2162 Thanks for the support! :)
Liked video before watch 😄I know it will going Perfect
Thank you!
11:51 - "You have to have the same schema for production & testing databases" & "You always need to clean up your testing database" - well yeah, that's how I program on Ruby on Rails. Takes just installing one plugin. Mocking your database is the worst thing you can do in Testing. Mocking is used to mock things that change from run to run (e.g. requests to a remote server, Time.Now() request, probably some other things).
13:17 - There's nothing wrong with having a hundred dependencies if they all make you able to deploy your features faster and with higher quality. Why reinvent the wheel if someone made a plugin? Maintenance of incompatibility between plugins is not as bad as reinventing say a State Machine library in every project.
I can see how having hundreds of dependencies could be considered fine, but you really want a bit more simplicity per class. This comes back to the Single Responsibility Principle. If you have hundreds of dependencies (I know you were exaggerating, I'm just using that same language) then your class/method is probably doing too much. For example, if a method has a dependency on HTTPClient and IDataAccess, that's probably too much. Talking to the web and talking to the database is probably a violation of SRP. Add in an IEmailClient and a ISmsClient and now you are doing way too much in one method. At that point, you aren't doing unit testing, you are doing integration testing.
Hi Tim, I am trying to combine the mocking with many other areas. But get a little stuck. In one of your other videos you have a line with something like:
var x = await _sqlDataAccess.LoadData(usp, new { LanguageID = LanguageId });
This is kind of a combination of my classes with your logic. It looks like that dynamic is not supported by moq and xunit. With I replace it here with a single int it works. But that brings too much restrictions to use this line for other options. So, I thought to replace it with a List but then again it doesn't work.
I am doing debug test and at the time it should give me back a result from the Mock it shows Null.
Also I was thinking if I bring the parameter maybe as a tuple into the dataAccess class and convert it there to an List
The project that I am working on are in .Core 3.1 and the test project is .Net standard 2.0
I believe it should support dynamic but if it doesn't, you can always create your own mock manually of the sqlDataAccess class. Just create your own class that implements the interface and put your mocked code in the methods.
@@IAmTimCorey thanks, will have a look at it. Just doing some other things at the moment. You will see another reply in another video for that.
Hi Tim, how the test at minute 51 realize, that the sql is wrong with the integer value?
When we passed in our known values, we knew what the resulting SQL string should look like. When it did not look the way we expected, we knew we had an issue. It compared the two strings to be sure they were the same. They weren't. Therefore, our expectations did not match our code's reality.
another great video!
Thank you.
Thank you very much Tim, really helped me to learn @~>. Keep on the great content!
You are welcome.
Hello Sir , thank you for all tutorials. Also , if you can make intermediate Web api project from scratch, it would be perfect for us. ( I finished your Web api tutorial and it was awesome. That's why I wanted one more full project :) )
Thank you again for your all videos Sir.
It is on the agenda. Thanks for the suggestion.
I have been learning so many things from you through years and used them in my projects. I appreciate your hard work. You have a great way of explaining everything; however, just as my personal opinion, you repeat the same thing in many ways that may waste time. I am waiting to see how you mock the database for a while and you are explaining how mock is spelled, repeating why _database is needed a few times, etc.
I am using the IDataAccess (DataLibrary) you made in another video, but I got a System.NullReferenceException on the actual list in the unit test.
How does the unit test (especially the setup) look like if using the DataLibrary from your video "Connecting C# To MySQL Using Blazor"?
I am not directly returning the output, but putting it in a global list and return it in a getter method.
thanks for theexcellent video. Can you please tell me how to test a data layer function which calls stored procedure? Your eg shows simple queries but how do i test a function which calls SP
Check to make sure it makes the call (mock the actual item it is calling) and make sure the inputs are correct for what you expected.
@@IAmTimCorey cool..but am little confused because how do i mock command object. Eg IDbCommand command = GetCommand(con)) {command.comandText="someSPName"}.
what is confusing me is how do i mock the spname..like syntax etc...can u please provide an eg if possible
Hi Tim,
If you are bypassing the code of SQLLiteDataAccess class than why do we need the moq library for mocking.
We can simply have two classes implementing ISQLDataAccess where one would return the actual data from DB and the other mock class will return the mock data.
So we can create our app context at the starting of our app where all the interfaces would have the actual data access classes and from the testing project the context interfaces will have the mock classes
Here using moq requires lot of code to be written as well as adding a library in your project
Correct me if I'm wrong
What you are proposing is to write a class to mock the implementation. That is what Moq does for you in a more dynamic manner. It allows you to make a simple mock (you don't have to mock everything, just what you are using) and it allows you to change the output values to test various scenarios (something your actual implementation would have a harder time doing).
@@IAmTimCorey Hi Tim,
We can also achieve testing different scenarios using mock classes and return the output on the basis of some reference IDs.
By using mock classes all the mock return code would be in mock classes and our unit test functions would have just assertion code.
In moq we need to write objects of moq classes than use create setup functions
All these code isn't required.
I have implemented the mock classes in my company although I can't share the code but I will write some short demo code and will present that to you in sometime.
With moq you can configure it to return different data for different scenarios. Therefore there is greater flexibility than if you hardcoded a result into a class and you won’t end up with loads of classes you have created to use in a single test. Having said that I do use a fake class in many cases when I just need an instance and I am not testing it.
Great video Tim thanks. Never really done any unit testing as the firms I've work at don't seem to do them, so never really got into them. AutoFac... Looks like I missed a video - DI With AutoFac - YT seems to think I've watched it. I'll have to go and watch that now as I had no idea what AutoFac is.
It is definitely a good one to learn.
Great Video!!!
Thanks!
Hi Tim, love your videos. I am a junior - mid level software engineer trying to bring some implementation tests to my company. We use entity framework with a database for each of our clients where each DB has the same table structure (same tables and columns within those tables across all dbs). Do you have any suggestions on what framework/Design pattern to use to achieve this?
Sorry, I'm not sure I understand. Are you saying you want to do implementation testing on your clients' installations? If so, that sounds like something you want to build custom since it is post-deployment.
Thanks for the video. What are my options for Live Testing if I only have Visual Studio Community 2022? This live testing tool is very handy
Awesome video but I didn’t got a grasp of one important thing. Almost always I am using stored procedures for Dapper. Should I put sql syntax into my tests directly only for the sake of testing or Moq somehow is learning about stored procedures existing in the database? Don’t understand how to test repository in my application which contains tons of different stored procedures. Sorry if my question was a bit clunky and demonstrates my utter ignorance.
Personally, I don't unit test my stored procedures. They don't have logic in them almost ever beyond the filtering and sorting of data. That means I don't need to have SQL in my unit tests in C# because I'm not testing the results of the queries. Instead, I can mock the results so that I can test my actual C# code.
Hi Tim, in some next videos, could you explain something about SignalR? What do you think about this subject?
It is on the list. It is a great technology for certain situations and definitely deserves to be covered.
When you have a large number of classes that are injected in the class that you want to test. Is that a sign that it's a method that you shouldn't test because it might be too large?
Or can I test them anyway. My question is really if you have like repo, Service and controller setup in your API should you test Services ? Service often has more business logic and do you test business logic with Unit test.
Does it do work? Then it should be tested, regardless of how many dependencies it has. And yes, you test business logic with unit tests.
@@IAmTimCorey Thanks for the reply, it might be obvious to test everything but starting testing a large project without tests is a bit much to chew in.
Hi Tim Corey,
Hope you're doing well. I watched your all video series it help me alot in real time.
I'm struggling for writing unit test using xunit framework. One for the method is inserting records into SQL db. I have written unit test case for this method but in the end cmd. executenonquery throwing exception like below
"BeginExecuteNonQuery requires an open and available connection. The connection currently state is closed"
I believe I need to mock sqlconnection any suggestions from your end. Appreciated
The first step is to identify what logic you are trying to test. Are you testing that the insert method is called or are you trying to test that the record was inserted? Unless your insert method is performing some logic, it does not need to be tested. If it is doing some logic on the inserted data, separate that logic from the actual insert (single responsibility principle) and then test just the logic method.
@@IAmTimCorey great to here thank you for your quick response,
I'm trying to test valid/invalid dummy data inserting into db but without hitting db it's should work till now no luck. I think I'm not sure I need to add config file into my test project and then i need to mock it.
Please suggest is that right way I'm think?
Again Appreciated..!
I always feel like I'm close to understanding the purpose of mocking. But I never really get there by watching videos. The examples I see is basically just tests to see if hard coded values matches other hardcoded values. It feels like we are not really getting a unit-test but more a new kind of interface thats ment for parameters and return values. Since the Mocks I have seen so far is saying "this is what this function needs to do. Every time. It needs to have this parameter or maybe this return value". But if its that static why dont we just use normal Asserts for this without Mocks since the mocked values are hardcoded in the end. Maybe its just because beginner examples are not complex enough. But it would be interesting to see a example of where a mock-test actually secures code.
Getting a failed test every time a method returns something else or uses a different param then a specific case seams kind of.. troublesome.
The purpose behind mocking is to remove that item as a dependency. We aren't testing that item, we are testing the method that uses that item. That's why we set it to return a known value every time. We want to test what happens when that value comes back to them method. We can control the inputs in order to test how they are used.
If you are using SQL Server not Sqlite (ISqliteDataAccess) what Interface file do you use and where can I get it? Thanks in advance.
nice, thanks
You are welcome.
I haven't gone through the whole video yet, but you have many assertions per tests. I always thought you should write one assert statement per test?
You should test one thing per test but you can have multiple asserts if you have more than one thing to check. No reason to write four tests to test the exact same thing just so you can assert on different parts.
It is not a hard and fast rule to have a single assert per test. You could have a logical set of asserts per test.
@@IAmTimCorey ah got it, one action and 'n' assertions to test the result of that action
I love the stuff with Moq, but due to the fact that extension methods are not supported, when you want to mock the ILogger it becomes a real mess (LogDebug, LogInformation are extension methods) :(
You can only use the plain Log method, which is quite impractical.
What is your opinion on this?
In our project using the "Microsoft.TeamFoundation.VersionControl.Client" references, how to mock and write unit testcases.
Awesome video. Can you please help with ADO.Net + Repository pattern + Unit testing in .Net core? Only quick sample is enough. I am facing issues with mocking stored proc and proper repository arrangements. Thanks.
I will add it to the list. Thanks for the suggestion.
1+
I wanted to ask how to go about applying testing to following scenario in following .NET Core App:
Class A is a Background service that consumes a message from a Rabbit queue.
Class B is a "MessageProcessor" class. It has a public method.
This method makes a call to a private method that invokes a public method of Class C. So Class B has a dependency on Class C.
Class C is a class that makes REST API call to an external API.
Do I have to put all 3 classes under separate tests or does it depend on what to test/what I should be testing?
So if I wanted to test the behaviour of processing a message I would put Class B under test and mock it's dependencies appropriately.
My current understanding is that I should be testing specific behaviour. Is that right?
Hey, Tim. Your lessons are great and I am following them. My advise is to focus on concrete facts. Too much history.
Thanks for the feedback. I believe in giving context for what I am teaching and that takes time. My goal is not entertainment but true education.
Hey Tim, love your videos.. I like how you explain things. One question, my project test doesn't run at all. It does spin but at the end it just says something like "0 tests ran, 0 tests failed, 0 tests skipped." Also, the test says "Excluded from Live Unit Tests" and I'm right-clicking and choosing "Include...." doesn't seem to have an effect. Thanks!
Not sure why you are getting that issue. It sounds like something isn't configured properly but I don't know what that might be.
@@IAmTimCorey Well, I forgot to add the xunit.runner.visualstudio.. Oops.. Thanks for replying Tim!
What do you do if your public method you're testing calls a private method that gets data from a db? How do you mock the private method so you can return fake data?
I don't mock private methods. I rework the dependencies. It sounds like you have a dependency (data access) that is not easily replaceable. That is something to work on fixing. Doing so will not only make your unit testing easier, it will also lead to a better design.
@@IAmTimCorey Hmm, so we have a Data Access Layer and inject the dataContext into the class. I really like your idea, but I'm not entirely certain of how I could go about refactoring this. We are using the repository pattern and have a controller calling a repo's public method (which is what I want to test). In that public method we have a private method that takes an id, joins 3 tables together, and returns some information. The public method then uses that information for more calculations. So what would that look like, or how would you go about implementing what you mentioned?
Do you have a video that talks about this? We are using dotnet core 3.1 if that helps.
@@IAmTimCorey Ok, I will try to move that out. If I move that piece out of the repository method, but I still have a private method that does some calculations with that data, should I move that to the DAL folder as well or keep it private?
Hello Tim, how do I turn on the check marks in my Visual Studio Enterprise? Thanks!
In the Test menu, turn on Live Unit Testing.
This feature is called Live Unit Testing in visual studio and its only available in the Enterprise edition
HI Tim,
Very informative , this will help me in some way.
I am facing some issue in mocking like I have created one integration Test based on CRUD operation but it was talking to real data ..how to mock this integration test (mock request response to create data and than update and delete it.
The principle is the same as what I covered in this video.
Hi!, Great videos about testisng. One question, do you have any video to learn how to effectively moq Entitify framework DbContext and DbSet that can be seen as Unit of work and Repository pattern? Perhaps it is better in this case to use a real database in memory like localdb, memorydb o sqlite on memory?
I don't have a video on that, sorry. It can be tricky to mock these.
As Tim said, it is difficult if not impossible to directly mock EF native classes.
What I have done before is abstract/wrap all of EF, so that in business logic we never reference any EF objects/types directly.
Instead all access is done through our own wrapping interfaces and class implementations that contain all our CRUD business logic etc.
Then all of these interfaces and types can be injected as per usual, and then easily tested and mocked etc.
For example:
// Generic base interface to represent a repository/set of any entity type T. Also supports IEnumerable, IQueryable etc.
interface IRepository : IEnumerable, IQueryable {
IEnumerable GetAll(); T GetById(int id); T Add(T new); T Update(T changed); void Delete(T); void Delete(int id); // Etc...
}
// Generic base implementation of the Repository interface using EF DbSet (in a DbContext). Again generic type T is an entity type.
public abstract class Repository : IRepository {
protected readonly DbSet _dbSet;
public Repository(DbSet dbSet) { _dbSet = dbSet; }
// Includes base implementation for IQueryable & IEnumerable; most else abstract. ....
}
// Example of specific repository interface for a repository/set of Persons, and extends the generic interface above.
interface IPersonRepository : IRepository { ... void MyCustomMethod(); ... } // Can also add extra custom methods here
// Example of specific class implementation of a repository/set of Persons using EF DbSet (in a DbContext).
public class PersonRepository : Repository, IPersonRepository {
public PersonRepository(DbSet dbSet) : base(dbSet) { } //...etc
public Person GetById(int id) { return _dbSet.FirstOrDefault(x => x.Id == id); } //...etc
public void MyCustomMethod() { /*Does Something*/ }; //...
}
// IDataContext interface with a get property for every repository/set class for each type of entity.
interface IDataContext { //...
IPersonRepository Persons { get; }
//... all other repository/entity types...
}
// Implementation of IDataContext using EF DbContext and EF DbSets etc. All repository/set properties use lazy init.
public class EFDataContext : IDataContext {
private DbContext _dbContext; // Can inject EF DbContext or instantiate in ctor etc.
//...
public virtual IPersonRepository Persons { get {
if (_persons == null) _persons = new PersonRepository(_dbContext.Persons); // Lazy init with EF DbSet.
return _persons;
} }
private IPersonRepository _persons; // Field for lazy init.
// Repeat pattern for for all entity types...
}
We did nearly of this using code-generation from EF T4 templates, similar to how EF POCO entity data model classes are created out of the box.
We extensively modified these T4 templates to also create/update all the extra interfaces and repository classes, which is absolutely necessary for 200+ entity types.
But if you only have a few entity types this could be done by hand fairly quickly. You would probably also want to make use of partial classes, so you can code-gen half the Repository into one
Obviously the code in the EFDataContext class cannot be unit tested, but it doesn't need to be since it is code-generated.
Then you can pass/use only IDataContext and IPersonRepository (etc) in your business logic, all of which can be easily mocked and tested.
Also then you can entirely swap out EF with a different ORM if you wanted to as well, since we've basically created a generic ORM interface.
However the code generation (in our case) was coupled with the EF code gen and the EF EDMX model etc.