I test di persistenza dovrebbero dipendere dall'implementazione del livello di accesso ai dati?

3

Attualmente stiamo sviluppando il livello di accesso ai dati di un'applicazione CRUD. Abbiamo la seguente struttura:

  • Abbiamo entità aziendali che vengono utilizzate al di fuori del livello di accesso ai dati per eseguire la logica di business.
  • Abbiamo entità DAO che vengono utilizzate nel livello di accesso ai dati per archiviare i dati nel nostro database. Queste entità sono solo oggetti dati che mappano uno a uno nelle nostre tabelle di database. Vivono all'interno del nostro livello di accesso ai dati e non possono essere utilizzati al di fuori di questo livello.
  • Abbiamo una classe, chiamiamola DatabaseAPI , responsabile che offre l'API crud per le nostre entità aziendali. Ad esempio, ha il metodo EntityX createEntityX(EntityX entityToCreate) dove EntityX è un'entità aziendale. Questo metodo è responsabile della trasformazione dell'entità ricevuta nelle entità DAO corrispondenti (alcune entità aziendali mappano a più di un'entità DAO), salva le entità DAO e trasforma e restituisce le entità DAO risultanti all'entità aziendale.

Al momento stiamo discutendo su come testare correttamente i metodi DatabaseAPI . In particolare abbiamo la seguente restrizione: EntityX ha un campo nome, non può esistere due EntityX s con lo stesso nome. Questa restrizione viene applicata da DatabaseAPI (attualmente come un vincolo univoco nel nostro database, ma potremmo utilizzare una query all'interno di una transazione per controllarlo manualmente), pertanto stiamo aggiungendo un test per verificare che tale restrizione sia applicata correttamente, tuttavia abbiamo il seguente disaccordo:

  • Penso che il test dovrebbe creare un EntityX con un nome dato Y utilizzando il metodo createEntityX . Quindi prova a creare un altro EntityX usando lo stesso nome Y , di nuovo con il metodo createEntityX , e verifica che non abbia esito positivo con l'eccezione corretta.
  • Il mio collega pensa che dovremmo creare un EntityXDAO , l'entità DAO corrispondente (o le entità se ce ne sono più di una), con nome Y nel test (manualmente, poiché i metodi DatabaseAPI non accettano DAO entità nella sua API di progettazione). Quindi prova a creare un altro EntityX utilizzando lo stesso nome Y , questa volta utilizzando il metodo createEntityX e verifica che non abbia esito positivo con l'eccezione corretta.

Quindi sostanzialmente, non siamo d'accordo sull'impostazione del test. Il mio ragionamento è:

  • Le entità DAO sono un dettaglio di implementazione e dovrebbero essere evitate nei test.
  • La restrizione che stiamo testando riguarda EntityX , non circa EntityXDAO . Pertanto, il test dovrebbe essere in termini di EntityX .
  • Abbiamo già un test precedente che verifica che createEntityX crei correttamente EntityX quando non ci sono conflitti.

Il ragionamento del mio collega è:

  • Nel mio test proposto, utilizzeremmo il metodo createEntityX per l'impostazione di test e quindi utilizzandolo nuovamente per il test effettivo, verificando che createEntityX generi l'eccezione corretta se esiste già un'entità con il nome specificato.

La domanda è, nel caso in cui la nostra configurazione di prova utilizzi il metodo createEntityX nella sua configurazione? Dovremmo creare manualmente le entità DAO richieste? C'è qualche alternativa che ci manca?

Codice di esempio:

void myTest()
{
    EntityX entityToCreateInDatabase = instantiateBusinessEntityX()
    databaseAPI.createEntityX(entityToCreateInDatabase)
    Assertions.assertThrows(MyDuplicityError.class, () -> databaseAPI.createEntityX(entityToCreateInDatabase))
}

void coworkersTest()
{
    EntityX entityToCreateInDatabase = instantiateBusinessEntityX()
    databaseAPI.getEntityDAO<EntityXDAO, Long>().create(new EntityXDAO(entityToCreateInDatabase))
    Assertions.assertThrows(MyDuplicityError.class, () -> databaseAPI.createEntityX(entityToCreateInDatabase))
}
    
posta jesm00 12.10.2017 - 16:29
fonte

1 risposta

1

Sembra che tu sia confuso riguardo a che cosa stai testando e che potrebbe spiegare perché non sei d'accordo su come testare

.

dichiari:

therefore we are adding a test to check that such restriction is correctly enforced

Stai verificando che quando l' origine dati esterna utilizzata da DatabaseAPI dice EntityX con nome Y esiste già, DatabaseAPI dovrebbe generare un'eccezione. Questa fonte di dati esterna dice che EntityX con nome Y esiste già restituendo effettivamente un DAO corrispondente al EntityX che stai cercando (almeno fino al suo nome).

Quindi, puoi semplicemente fare questo:

void myTest()
{
    Mock dataSourceMock = mock(DataSourceInterface)
    when(dataSourceMock)->receive('findEntityX')->with('name', 'Y')->return(new EntityXDAO(entityToCreateInDatabase))
    DatabaseAPI databaseAPI = instantiateDatabaseAPI(dataSourceMock)
    Assertions.assertThrows(MyDuplicityError.class, () -> databaseAPI.createEntityX(entityToCreateInDatabase))
}

Dove DataSourceInterface dovrebbe essere implementato dal tuo livello attuale del database che esegue le query.

    
risposta data 12.10.2017 - 17:13
fonte

Leggi altre domande sui tag