Test - Bellek İçi DB ve Alay Etme


12

Testler yazarken, neden birisi sadece verileri alay etmek için bellek içi bir veritabanı kullanmak isteyesin ki?

Bellek içi veritabanlarının bir kişinin depolarını test etmek için yararlı olabileceğini görebiliyordum. Ancak bir çerçeve (Spring Data gibi) kullanılıyorsa, havuzları test etmek, gerçekte uygulama mantığını değil, çerçeveyi test eder.

Ancak alay, daha hızlı görünüyor ve birim testleri ve TDD yazarken genellikle kullanılan aynı modeli izliyor.

O zaman neyi özlüyorum? Bellek içi veritabanı ne zaman / neden yararlı olur?

Yanıtlar:


14

Mocking, birim testleri için ideal bir çözümdür ve hızı artırmak için entegrasyon testleri için de kullanılabilir, ancak bellek içi bir veritabanı kullandığınızla aynı düzeyde güven vermez. Tüm uygulamayı, üretimin nasıl yapılandırıldığına olabildiğince yakın şekilde yapılandırdığınız uçtan uca testler yazmalı ve buna karşı otomatik testler çalıştırmalısınız. Bu testler gerçek bir veritabanı kullanmalıdır - bellek içi, docker, VM veya başka bir dağıtım.

Ancak bir çerçeve (Spring Data gibi) kullanılıyorsa, havuzları test etmek, gerçekte uygulama mantığını değil, çerçeveyi test eder.

Gerçek bir veritabanı kullanarak, çerçeveyi doğru şekilde yapılandırıp kullandığınızı test edersiniz. Ayrıca, çerçevede sadece gerçek bir veritabanı ile test edilirken ortaya çıkan eksiklikler olabilir (kabul edilen örnek: Spring Data, PostgreSQL'in 9.2 sürümünü desteklemez).

Test kapsamımın çoğunu alay konusu kaynaklara karşı yazardım, ancak gerçek bir veritabanı kullanarak yaygın olarak kullanılan kullanım durumları için uçtan uca testler yazarım.


Bir Birim testi ise, çerçeveyi çerçeveyi kullanan katmandan ayrı olarak test edersiniz. Tüm birim testleri yapıldıktan sonra daima bazı entegrasyon testleri yapılmalıdır.
Denise Skidmore

2

Çoğu zaman, bellek içi veritabanı testi alaydan daha basittir. Aynı zamanda çok daha esnektir. Ayrıca, geçiş dosyalarının iyi yapıldığını da test eder (geçiş dosyaları olduğunda).

Bu sahte kodu görün:

class InMemoryTest 
{
    /** @test */
    public function user_repository_can_create_a_user()
    {
        $this->flushDatabase();

        $userRepository = new UserRepository(new Database());
        $userRepository->create('name', 'email@email.com');

        $this->seeInDatabase('users', ['name' => 'name', 'email' => 'email@email.com']);
    }
}

class MockingDBTest
{
    /** @test */
    public function user_repository_can_create_a_user()
    {
        $databaseMock = MockLib::mock(Database::class);
        $databaseMock->shouldReceive('save')
                     ->once()
                     ->withArgs(['users', ['name' => 'name', 'email' => 'email@email.com']]);

        $userRepository = new UserRepository($databaseMock);
        $userRepository->create('name', 'email@email.com');
    }
}

Bu InMemoryTest, işe nasıl Databaseuygulandığına bağlı değildir UserRepository. Sadece UserRepositorygenel arabirimi ( create) kullanır ve sonra ona karşı ekler. Uygulamayı değiştirirseniz bu test kırılmaz ancak daha yavaştır.

Bu arada, MockingDBTestnasıl Databaseuygulandığına tamamen güvenir UserRepository. Aslında, uygulamayı değiştirir ancak yine de başka bir şekilde çalıştırırsanız, bu test kırılır.

Her iki dünyanın en iyisi , arayüzü uygulayan sahte bir yöntem kullanmaktır Database:

class UsingAFakeDatabaseTest
{
    /** @test */
    public function user_repository_can_create_a_user()
    {
        $fakeDatabase = new FakeDatabase();
        $userRepository = new UserRepository($fakeDatabase);
        $userRepository->create('name', 'email@email.com');

        $this->assertEquals('name', $fakeDatabase->datas['users']['name']);
        $this->assertEquals('email@email.com', $fakeDatabase->datas['users']['email']);
    }
}

interface DatabaseInterface
{
    public function save(string $table, array $datas);
}

class FakeDatabase implements DatabaseInterface
{
    public $datas;

    public function save(string $table, array $datas)
    {
        $this->datas[$table][] = $datas;
    }
}

Bu çok daha etkileyici, okunması ve anlaşılması daha kolaydır ve kodun daha üst katmanlarında yapılan gerçek Veritabanının uygulanmasına bağlı değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.