2012-01-13 2 views
2

В моем проекте я следую схеме репозитория. Мои репозитории разговаривают с уровнем сдерживания, и я использую Entity Framework в качестве ORM.Единичные репозитории тестирования

В настоящее время, в моих модульных тестах, я кодирую непосредственно против уровня сохранения, и в результате любой тест выполняется непосредственно против БД. Итак, если я тестирую для вставки, он фактически вставляет данные в базу данных.

Я хочу знать, как я могу протестировать, не беспокоясь о том, чтобы изменить базу данных?

Есть ли способ, который я могу сделать в области тестирования базы данных?

Благодаря

Я создал схему базы данных, подобную реальной один в моем App_Data, а затем я попытался его реализации, как это -

[TestInitialize] 
    public void TestInitialize() 
    { 

     //TODO: in TestCleanup, do a rollback to revert any changes performed during the test. 
     Database.SetInitializer<LogViewerDbContextFake>(new LogViewerInitializer()); 
    } 

    [TestMethod] 
    public void Get_Should_Return_List_Of_Applications() 
    { 
     // Arrange 
     LogViewerDbContext testDbContext = new LogViewerDbContextFake(); 
     ApplicationRepository sut = new ApplicationRepositoryImpl(testDbContext); 

     // Act 
     List<string> failure = sut.Get(); 

     // Assert 
     Assert.AreEqual(4, failure.Count); 
    } 

internal class LogViewerInitializer : DropCreateDatabaseIfModelChanges<LogViewerDbContextFake> 
{ 
    protected override void Seed(LogViewerDbContextFake context) 
    { 
     List<LogEntry> logEntries = new List<LogEntry>() 
     { 
      new LogEntry{ 
       Id = 1, 
       Application = "Application 1" 
      }, 
      new LogEntry{ 
       Id = 2, 
       Application = "Application 2" 
      }, 
      new LogEntry{ 
       Id = 3, 
       Application = "Application 3" 
      }, 
      new LogEntry{ 
       Id = 4, 
       Application = "Application 4" 
      }, 
      new LogEntry{ 
       Id = 5, 
       Application = "Application 2" 
      }, 
      new LogEntry{ 
       Id = 6, 
       Application = "Application 2" 
      } 
     }; 

     logEntries.ForEach(s => context.LogEntries.Add(s)); 
     context.SaveChanges(); 
    } 
} 

Даже если тест побежал и прошел, LogViewerInitializer не вставили какой-либо записи в App_Data \ Database. Итак, мне было интересно, какова логика и как именно происходит выполнение?

+0

Настройка базы данных тестирования. – Ryan

ответ

1

Используйте блок TransactionScope, чтобы избежать передачи данных в базу данных.

using (TransactionScope scope = new TransactionScope()) 
{ 
    // test goes here 

    db.SaveChanges(); 

    // assertions  
} 
+0

Я думаю, что это неправильный подход. IMO в модульных тестах никогда не должны пытаться получить доступ к базе данных. Если вы не являетесь модульным тестированием. –

+0

@LukeMcGregor Тестирование модуля EF-зависимый код не выявит многих проблем, если вы не попали в базу данных и не использовали Mocks/Fakes. Например, использование метода расширения «Last» в LINQ-to-Entities не будет работать, но работает с LINQ-to-Objects. Поэтому ваши юнит-тесты пройдут, но код неверен. Таких примеров много. – Eranga

+0

Это фактически интеграционное тестирование. Вам нужно протестировать логику изолированно, ее нельзя тестировать одновременно с тестированием между границами таких систем, как в этом случае –

0

Вы пытались использовать насмешливый фреймворк, такой как Rhinomocks или MOQ, чтобы издеваться над персистентным слоем?

Альтернативно вы можете сделать аргумент о том, что вы на самом деле выполняете сквозное тестирование и удаляете данные из базы данных после запуска теста. Вы делаете это, запустив сценарии post и pre sql до и после запуска теста с использованием атрибутов. Если вы используете структуру AOP, такую ​​как PostSharp, это делает ее очень простой. Если нет, вы все равно можете сделать это с помощью контекстных объектов, как я объяснил. here

0

Я построил свою собственную структуру репозитория для этого, используя ninject и EF. Взгляните сюда, если вам интересно, у меня также есть пример того, как использовать мою инфраструктуру репозитория для создания простых модульных тестов.

http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html

+0

Я до сих пор пытался реализовать его так – annantDev

Смежные вопросы