I am trying to start unit testing an MVC2 project, which uses the Entity Framework. When I run my "hello world" test, it fails saying this:
The specified named connection is
either not found in the configuration,
not intended to be used with the
EntityClient provider, or not valid.
How can I pass the connection data (which were generated by the Entity Framework and are in the main Web.config) to the testing project?
Thanks
Depending on what unit testing framework you use you could try adding an app.config to your test-project with the right settings for EF. This works with xUnit.Net and I'm pretty sure most other test-frameworks also support this.
For completeness I do need to warn you that tests that touch the database aren't unit-tests but integration tests. Those are useful too but can become a hassle to maintain when your code changes. It's usually a good idea to test small pieces of code in isolation, this gets around problems like you describe because you won't need to access the database at all.
I would recommended using Dev Magic Fake to Mock the UI without need to use Entity framework or even DB, using Dev Magic Fake, you can run your MVC project and run the unit test without need for any DAL
for more information http://devmagicfake.codeplex.com/
Thanks
Related
thank you for reading my question.
I was just wondering about how shall i create unit tests for existing database layer. as of now my project has existing unit tests but no unit test is written for database layer or any function which inserts / updates / deletes data from database.
We are using Microsoft tests. One approach I think here is
1) We shall create database on the fly i.e. mdf file and we will keep our defaults values ready in it and in our setup method(Nunit) or initialize method(MS tests) we will mock the objects and dump the dummy data into tables.
Also we are not using any mocking framework. So i am all confuse.
i need to know how can we do this from the scratch. Also is there anything optional available for mocking framework.
Any pointers or samples would be highly appreciated.
Thank you again.
A C# unit test shall not touch the database, you should mock the database. It should be possible to execute many thousands of unit test on your local machine (without external (internet, databases, other application)) within seconds (and you want to run them when you build your code).
That leaves us kind of with your question unanswered: what should your database layer tests do? It depends on what kind of logic you have in that assembly! If you have "business or decision" logic should should test that, if you have mapping logic test that. If all your database layer does if using (whatever db framework) to put the load on you database then you might not have anything worth testing there.
If you want to test logic performed by your database (say SP's) you should do that in the database project, and most likely not using mstest.
Of course you can use mstest to setup and tear down database and perform test, but those test will not be unit tests.
According to the Grails documentation
Unit tests are typically run without the presence of physical
resources that involve I/O such databases, socket connections or
files.
However, when I run my tests with the Grails cmd line tool it includes the Config.groovy meaning that in my tested code I have...
Integer daysToRetain = grailsApplication.config.com.gleason.assignmentRetentionDays as Integer
this resolves correctly without having to mock it. Also in my unit test I have the following...
import grails.util.Holders
...
Integer daysToRetain = Holders.config.com.gleason.assignmentRetentionDays as Integer
Why does grails load the Config.groovy if it is not a convention to use it? Also, what other files are OK to rely on?
Unit tests in Grails will bootstrap a minimally viable Grails runtime environment. This means configuration, but not necessarily loading the components or plugins that pertain to persistence (ie. hibernate datasources).
The Grails documentation doesn't speak to not being able to get a handle on the configuration during unit tests, given that the config is embedded within your project. Rather, it's speaking more to not necessarily having runtime server-local filesystem resources during your unit testing (esp if you're running in CI).
Also, what other files are OK to rely on?
Presumably anything resource within your project.
i personally would mock it out, because of one of the following reasons:
If you go the isolation path of unit testing, then obviously Config.groovy would not be the unit under test. So this means Config.groovy is an external dependency and to let the test not depend on an external dependency that could possibly change is a benefit, because then it could not break by a mistakenly Config.groovy change.
If you use grails plugins to decompose your grails app, then you the little wired situation, that in test mode, you have to define your configs in the plugin, because the unit-tests run in plugin local and in a run-app situation you have to set them in the app, because config.groovy is by default not exposed from the plugin (this is obviously not a big deal, but anyway).
But the other point here that i see is, that by mocking it out, you make it explicitly in your test, that you a expecting a certain path from the config (like com.gleason.assignmentRetentionDays), that you would otherwise you would just have to know, because its in your implementation.
Additionally it becomes more clear, when only reading the test, what values are set for this paticular config setting. This is not in all cases important, but sometimes it could be nice to know when reading the test.
We're using MVC, Entity Framework 4.1 Code First, SQL Server in our project.
Please share your experience: how do you unit test your data service layer? By data service layer I mean services supposed to be run by MVC controllers that have some kind of DbContext derived class declaration inside, so that they depend on this EF DbContext, and encapsulate some business\data logic to fetch and store the data.
After reading few articles and posts, I incline to use separate database to build unit/integration tests on, and I prefer to use in-memory (like SQLite) rather than SQL Compact. However I'm not even sure if it's possible, if you have such an experience, could be please share few lines of code to show how you achieve this.
Unit testing means testing unit = no database, no external dependency, just testing single testable unit. Once you want to involve database you don't unit test any more - you are doing integration testing.
I wrote multiple answers about unit testing / integration testing of code dependent on EF. The last one is here. So if your service layer creates linq queries on context you cannot reliably unit test them. You need integration tests.
I would use the same database as you expect to use in your real code. Why? Because mapping and behaviour between database provides can differ as well as implementation of LINQ. Also in case of SQL server you can use special EF features which don't have to be available in SQLite. Another reason is that last time I checked it, SQLite's provider didn't support database deletion, recreation, etc. which is something people usually want to use for integration tests. Solution for that can be Devart provider.
I don't use a separate database at all. In fact, my Unit Tests don't use a database at all.
My strategy is to create IEnityRepository interfaces for the DB Entities (replace Entity with the actual name). I then pass those to the constructor for my controllers.
During Unit Testing, I simply use a Mocking library to pass mock implementations of the repositories that I need and have the return some set of known data that I can use in the Unit Tests.
I must be doing something fundamentally wrong.
I am implmenting my repositories and then testing them with mocked data. All is well.
Now I want to test my domain objects so I point them at mock repositories.
But I'm finding that I have to re-implement logic from the 'real' repositories into the mocks, or, create 'helper classes' that encapsulate the logic and interact with the repositories (real or mock), and then I have to test those too.
So what am I missing - why implement and test mock repositories when I could use the real ones with mocked data?
EDIT: To clarify, by 'mocked data' I do not hit the actual database. I have a 'DB mock layer' I can insert under the real repositories that returns known-data.
Maybe your mixing your abstractions. maybe some of the helpers and logic that your talking about should be in your domain objects. Your repositories should be implementing a CRUD interface. So your domain logic should be using 8 actions from the repository. Good retrieve and Bad retrieve (exception thrown) are only two of the eight. One test, is how is the Bad retrieve handled in the domain object. The rest of the tests should be testing a Good retrieve.
Unit testing is meant to minimize the tested element -> test data route, in order to reduce search time if a bug occurs - the bug is either in the routine you test or the test unit and nothing else (well, maybe the OS or the compiler... but these are very rare).
Now imagine you made a database accessor module. The module seems to work ok. Then you make a config reader that reads from the database. Instead of a mock database accessor module unit test, you use your real database module on top of mock config data in the database test unit. It still seems to work OK. Now you add a GUI layer that uses the config object returned by the config reader unit. Instead of mocking the "boiled" config data you use the real module which apparently works.
And now your GUI stops working for a certain value. Where is the error? In the GUI, in the config reader, in the database accessor or in the values in the mock database?
In other words, you're not just testing the code you're writing, you're testing the real repository system as well, and if a bug is found you have an additional layer to analyze.
why implement and test mock
repositories when I could use the real
ones with mocked data?
I guess it really comes down to how much code coverage you think you need to have. If you feel the repository is sound and you can use it for testing, go for it. Perhaps the repository unit tests can be run prior to the mock database unit tests, so that you can use the real repositories for testing and feel confident that the testing is still valid.
I'm fairly new to unit testing. I have a site built in the 3-tier architecture, UI -> BLL -> DAL. And I used the asp.net Provider Model, so by making changes to web.config I can switch to DAL dll to target different data sources, to be complete the DAL is written with Entity Framework.
Now, my question is how do I unit test my BLL? I use NUnit.
If run/debug my site, the asp.net/IIS loads everything and gets the correct configuration from web.config, so things work, that is because the entry point is from IIS. Now if I use NUnit gui to test and say I have my test project "MySite.Test.dll" which have test cases to my BLL, how does the testing framework get the correct configuration to successfully run all the test. It needs the info in web.config to load the correct provider!
Now, in my DAL there is a App.config created there by EntityFramework, and in it there is just the connectionString. Should I put all the provider related configuration in this app.config? Or am I missing some big picture on how to correctly do this?
This should be a common thing I imagine people need to do constantly. Could someone give some detail on how do I unit test my lib.
Thank you,
Ray.
Edit: After reading the first 2 answers I think I should correct my description with integration testing. Basically instead of IIS as the entry point, use GUI tools like the NUnit to run and test my code through, so NUnit -> BLL -> DAL. How do people actually set it up?
Thanks,
Ray.
Looks like what you are trying to do - is integration testing...
Unit testing, by definition, testing Plain Old .Net Classes in isolation. No database, no configuration...so...as I see it, to do proper unit testing, you need to refactor your BLL to service layer and domain logic classes which you will test separately. Like: Service layer uses domain logic classes, and your unit test uses them. So, domain classes do not go to database, and you do not need connection strings and everything.
However, if you want to do proper integration testing with database, you might want to do that too. If this is what you need - google it, it's not difficult to get some configuration strings in nunit.config or something...I don't know the details.
However, I feel what you want to do is unit testing and not integration testing..
Ask yourself, WHAT EXACTLY DO I WANT TO TEST?
Unit testing does not test "everything". Refactor, invert dependencies, and try to test you business logic in isolation.
Instead of a "web.config" file in your unit test project, you'll need a "MySite.Test.dll.config" file instead where you can enter the correct configuration for the testing. Note, using this method you could use a different provider to connect to an in-memory database instead if you wanted.
You have a couple of different options depending on how isolated you want to be from the DAL. If you want to involve the DAL in your tests, then you can copy the connection string section of the app.config file to an app.config file in your unit test project. As #badbadboy says, though, this really is integration testing, not unit testing.
If you want to do proper unit testing you probably want to use dependency injection and interfaces to allow you to mock out the DAL from your BLL. I use LINQ-to-SQL so what I do is create an interface and wrapper class around the DataContext. This allows me to create a mock database to use for unit testing to test my entity classes in isolation.
Testing your entity classes in isolation will make your tests less brittle and allow you to set up the data for each test independently. This makes it much easier to maintain.
You also might want to look into a mocking framework that will make it almost trivial to generate the mock objects. I've had pretty good success with Rhino Mocks, but there are others.