Репозитории модульного тестирования - PullRequest
2 голосов
/ 13 января 2012

В моем проекте я следую шаблону репозитория.Мои репозитории общаются со слоем персистентности, и я использую 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.Итак, мне было интересно, что за логика и как именно все выполняется?

Ответы [ 3 ]

1 голос
/ 13 января 2012

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

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

     db.SaveChanges();

    // assertions    
}
0 голосов
/ 13 января 2012

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

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

0 голосов
/ 13 января 2012

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

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

...