62

We have a Visual Studio 2012 ASP.NET MVC project using Entity Framework 5.

There are some unit tests that depend on a database. Setting up the app.config file in the test project to use a central SQL Server database works fine.

However, it would be much nicer to use a LocalDb, so that each developer has his/her own database when running the tests. Especially since we would like to have the tests set up to DropCreateDatabaseAlways when running.

However, I can't get the setup to work. If I try this in app.config:

<add name="TestDb" 
   connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=unittestdb;
     Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\unittestdb.mdf"
   providerName="System.Data.SqlClient" />

I get:

System.Data.SqlClient.SqlException: A file activation error occurred. The physical file name '\unittestdb.mdf' may be incorrect. Diagnose and correct additional errors, and retry the operation. CREATE DATABASE failed. Some file names listed could not be created. Check related errors.

It sounds like it wants the mdf file to exist already, which seems strange since it is trying to create the database. Creating a mdf file manually does not change the error message.

Jeroen
  • 60,696
  • 40
  • 206
  • 339
Klas Mellbourn
  • 42,571
  • 24
  • 140
  • 158
  • 1
    Can you check what value do you have in unit test when you call: `AppDomain.CurrentDomain.GetData("DataDirectory")`? – Ladislav Mrnka Sep 03 '12 at 09:04
  • The value of `AppDomain.CurrentDomain.GetData("DataDirectory")` in the unit test is `null`. – Klas Mellbourn Sep 03 '12 at 09:36
  • 1
    So either set the value to some path by using `SetData` or don't use `|DataDirectory|` in the connection string because it is `null`. – Ladislav Mrnka Sep 03 '12 at 10:06
  • Removing the `|DataDirecotry|\` part does not help, I get the same error. However, replacing it with `C:\Temp\` does help! Then the unit tests run again. So that is a great improvement. Icing on the cake would be if the db could reside in a relative path. – Klas Mellbourn Sep 03 '12 at 10:35
  • I succeeded in getting a relative path after following the advice on [this question](http://stackoverflow.com/questions/125157/relative-path-reference-in-webconfig-connectionstring) – Klas Mellbourn Sep 03 '12 at 10:46
  • 2
    Since you've found a solution, can you answer your own question and accept the answer? – sharakan Jan 29 '13 at 14:14
  • NOTE: It may be safer to use (Localdb)\MSSQLLocalDB - that way tests won't break even if say SQL Express with localDB 2014 was installed (v12) vs SQL Express 2012 (v11) – Sudhanshu Mishra Jun 07 '16 at 07:31

5 Answers5

34

Try:

AppDomain.CurrentDomain.SetData(
  "DataDirectory", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ""));

This will Create Db File on /bin/Debug/yourdbname.mdf

Tim Post
  • 33,371
  • 15
  • 110
  • 174
zbw911
  • 343
  • 3
  • 3
10

I would use:

// Declare this property - this is set by MSTest
public TestContext TestContext { get; set; }

// In test initialization - note the signature should be exactly this
// A static void method with one argument of type TestContext 
[ClassInitialize]
public static void SetUp(TestContext context)
{
   AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(context.TestDeploymentDir, string.Empty));
}

You could get problems using AppDomain.CurrentDomain.BaseDirectory, instead use: context.TestDeploymentDir

Sudhanshu Mishra
  • 6,523
  • 2
  • 59
  • 76
Jupaol
  • 21,107
  • 8
  • 68
  • 100
3

Keep in mind that for a test project:

AttachDBFilename=|DataDirectory|

means it will look in your output /bin/debug folder for a unit test as opposed to the App_Data folder in your web/production/whatever app.

You need to do two things 1. Move the database file OUT OF your App_Data folder to your root of your test app. 2. Highlight your database so you get your properties window in Visual Studio. Set the build action to "Content" so it will get copied to your output folder when you run the project.

Voila.

Adam Tuliper
  • 29,982
  • 4
  • 53
  • 71
1

I suggest to use this code (based on the answer of Jupaol):

[ClassInitialize]
public static void SetUp(TestContext context)
{
    AppDomain.CurrentDomain.SetData(
        "DataDirectory", 
        context.TestDeploymentDir);
}

Usually this will create your database inside TestResults\<test run>\Out\ folder of your solution.

Community
  • 1
  • 1
Davide Icardi
  • 11,919
  • 8
  • 56
  • 77
  • Hi, Using VS 2013 this code works when I run my unit test in "Debug Tests" mode. But it fails when I run "Run All" tests. How can I make it work in "Run All" mode – Martin Feb 20 '14 at 17:57
0

I found your question while searching for answer to the problem. Using EntityFramework with nUnit in a separate project, I had to change the App.config

looked like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>
Gustavo Rossi Muller
  • 1,062
  • 14
  • 18