Come scrivere test unitari per un pezzo di codice che ha un contesto di dati?

2

Sono nuovo al test delle unità e utilizzo della libreria di test delle unità di Microsoft per la seguente parte di codice. Quando eseguo il codice normalmente viene eseguito correttamente, tuttavia quando eseguo il test unitario scritto per questo codice ottengo un errore di riferimento zero al momento dell'inizializzazione del datacontext.

Di seguito è riportato un metodo simile a quello che sto provando a testare:

    public int DeleteXYZTableRecord(int Id)
    {
        try
        {
            int XYZTableIdDeleted = -1;
            using (System.Transactions.TransactionScope scope = new System.Transactions.TransactionScope(System.Transactions.TransactionScopeOption.Required,
                                                           new System.Transactions.TransactionOptions { IsolationLevel =  System.Transactions.IsolationLevel.Snapshot }))
            {
                if (Id <= 0)
                {
                    throw new ArgumentException(InvalidIdMessage);
                }
                using (DBDataContext context = new DBDataContext()) //**exception occurs here**
                {//block inside using is irrelevant as its never executed due to the exception
                    XYZTable modifiedXYZRecord = context .XYZTables.Where(x => x.ID.Equals(Id)).FirstOrDefault();
                    if (modifiedXYZRecord == null)
                        throw new NullReferenceException(RecordNotFoundMessage);

                    if (modifiedXYZRecord .pqrRecords == null && modifiedXYZRecord .pqrRecords == null)
                    {
                        modifiedXYZRecord .status = 0;
                        context.SubmitChanges();
                        XYZTableIdDeleted = modifiedXYZRecord .ID;
                    }

                }
                scope.Complete();
            }
            return XYZTableIdDeleted ;
        }
        catch (Exception)
        {

            throw;
        }

    }

Ed ecco il metodo di prova che sto usando per testarlo:

    [TestMethod]
    public void DeleteXYZTest()
    {

        string exceptionName = String.Empty;

        try
        {

            var target = new DBService.UpdateData .XYZDBHandler();

            // Access the data
            int inputId = 1;
            int expectedOutputId = 1;

            int actual = target.DeleteXYZTableRecord(inputId);
            Assert.AreEqual(expectedOutputId, actual,
                "x:<{0}> y:<{1}>",
                new object[] { expectedOutputId, actual });
        }
        catch (Exception e)
        {
            StringAssert.Contains(e.Message, DBService.UpdateData.XYZDBHandler.RecordNotFoundMessage);

            return;
        }
        Assert.Fail("No exception was thrown.");
    }
    
posta Goldfish 07.01.2015 - 11:26
fonte

1 risposta

1

Affinché i test unitari funzionino devi essere in grado di prendere in giro tutte le dipendenze esterne dal tuo codice (altrimenti stai facendo un test di integrazione). Il tuo problema è che hai dipendenze dirette per le implementazioni di accesso ai dati. Questo è accoppiato con il problema che il tuo gestore sta facendo entrambi i lavori di gestione e è responsabile della creazione delle classi di accesso ai dati.

Quello che vuoi fare è astrarre il tuo livello dati. Questo è il più delle volte fatto con quello che viene chiamato modello Repository. Non è necessario, ma il punto è che hai bisogno di un livello di astrazione tra il gestore e l'accesso ai dati. Quindi generalmente passerai questa dipendenza dalla cosa che chiama il gestore. Questo è più spesso raggiunto con cose come quadri di iniezione di dipendenza, ma ancora una volta, non è necessariamente necessario andare così lontano.

Una volta che si conosce più a lungo una dipendenza da una classe concreta, è possibile utilizzare una struttura di simulazione per deridere le dipendenze di accesso ai dati. Prova Rhino o Moq, ce ne sono molti diversi. Dovresti prendere in giro l'interfaccia che invii al gestore e specificare cosa fa il gestore quando lo chiami. Ciò rimuove la variabilità delle dipendenze delle tue dipendenze e ti concen- triamo esclusivamente sulla funzionalità del codice che stai testando.

    
risposta data 11.01.2015 - 20:08
fonte

Leggi altre domande sui tag