Как настроить LocalDb для модульных тестов в Visual Studio 2012 и Entity Framework 5

У нас есть проект Visual Studio 2012 ASP.NET MVC с использованием Entity Framework 5.

Есть некоторые модульные тесты, которые зависят от базы данных. Настройка файла app.config в тестовом проекте для использования центральной базы данных SQL Server работает нормально.

Однако было бы намного лучше использовать LocalDb, чтобы у каждого разработчика была своя собственная база данных при запуске тестов. Тем более, что мы хотели бы, чтобы тесты были настроены на DropCreateDatabaseAlways при запуске.

Тем не менее, я не могу заставить настройку работать. Если я попробую это в 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" />

Я получил:

System.Data.SqlClient.SqlException: Произошла ошибка активации файла. Имя физического файла «\unittestdb.mdf» может быть неверным. Диагностируйте и исправьте дополнительные ошибки и повторите операцию. СОЗДАТЬ БАЗУ ДАННЫХ не удалось. Некоторые перечисленные имена файлов не могут быть созданы. Проверьте связанные ошибки.

Похоже, он хочет, чтобы файл mdf уже существовал, что кажется странным, поскольку он пытается создать базу данных. Создание файла mdf вручную не изменяет сообщение об ошибке.


person Klas Mellbourn    schedule 03.09.2012    source источник
comment
Можете ли вы проверить, какое значение у вас есть в модульном тесте, когда вы вызываете: AppDomain.CurrentDomain.GetData("DataDirectory")?   -  person Ladislav Mrnka    schedule 03.09.2012
comment
Значение AppDomain.CurrentDomain.GetData("DataDirectory") в модульном тесте равно null.   -  person Klas Mellbourn    schedule 03.09.2012
comment
Поэтому либо установите значение на какой-либо путь, используя SetData, либо не используйте |DataDirectory| в строке подключения, потому что это null.   -  person Ladislav Mrnka    schedule 03.09.2012
comment
Удаление |DataDirecotry|` part does not help, I get the same error. However, replacing it with C:\Temp` действительно помогает! Затем модульные тесты запускаются снова. Так что это большое улучшение. Вишенкой на торте было бы, если бы БД могла находиться на относительном пути.   -  person Klas Mellbourn    schedule 03.09.2012
comment
Мне удалось получить относительный путь, следуя совету по этот вопрос   -  person Klas Mellbourn    schedule 03.09.2012
comment
Поскольку вы нашли решение, можете ли вы ответить на свой вопрос и принять ответ?   -  person sharakan    schedule 29.01.2013
comment
ПРИМЕЧАНИЕ. Может быть безопаснее использовать (Localdb)\MSSQLLocalDB — в этом случае тесты не сломаются, даже если, скажем, установлен SQL Express с localDB 2014 (v12) по сравнению с SQL Express 2012 (v11)   -  person Sudhanshu Mishra    schedule 07.06.2016


Ответы (5)


Пытаться:

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

Это создаст файл базы данных в /bin/Debug/yourdbname.mdf.

person zbw911    schedule 04.02.2013

Я хотел бы использовать:

// 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));
}

У вас могут возникнуть проблемы с использованием AppDomain.CurrentDomain.BaseDirectory, вместо этого используйте: context.TestDeploymentDir

person Jupaol    schedule 08.03.2013
comment
Что за тип context и откуда он взялся? - person Jesse Webb; 18.11.2013
comment
Добавьте подобное свойство в свой тестовый класс, и MSTest внедрит его за вас public TestContext TestContext { get; set; } - person Jupaol; 19.11.2013
comment
Можете ли вы объяснить, почему делать это в методе настройки лучше, чем непосредственно перед моим new Migrations.Configuration();? - person bbodenmiller; 07.03.2017

Имейте в виду, что для тестового проекта:

AttachDBFilename=|DataDirectory|

означает, что он будет искать модульный тест в вашей выходной папке /bin/debug, а не в папке App_Data в вашем веб-/производственном/любом приложении.

Вам нужно сделать две вещи: 1. Переместить файл базы данных ИЗ папки App_Data в корень вашего тестового приложения. 2. Выделите свою базу данных, чтобы открыть окно свойств в Visual Studio. Установите для действия сборки значение «Содержимое», чтобы оно копировалось в выходную папку при запуске проекта.

Вуаля.

person Adam Tuliper - MSFT    schedule 19.11.2013

Я предлагаю использовать этот код (на основе ответа Jupaol):

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

Обычно это создает вашу базу данных внутри папки TestResults\<test run>\Out\ вашего решения.

person Davide Icardi    schedule 24.11.2013
comment
Привет! Используя VS 2013, этот код работает, когда я запускаю свой модульный тест в режиме отладки тестов. Но это не удается, когда я запускаю все тесты. Как я могу заставить его работать в режиме Run All - person Martin; 20.02.2014

Я нашел ваш вопрос, когда искал ответ на проблему. Используя EntityFramework с nUnit в отдельном проекте, мне пришлось изменить App.config

выглядело так:

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

person Gustavo Rossi Muller    schedule 21.10.2014
comment
И это сработало для UnitTest с использованием атрибута DataSource? - person JWP; 04.11.2016