2014-10-28 4 views
8

Ho il seguente metodo di supporto, che accetta i messaggi di convalida dalla DbEntityValidationException. Ne abbiamo bisogno perché i dettagli della convalida non vengono aggiunti all'eccezione per impostazione predefinita.Come creare un test unitario per un oggetto che dipende da DbEntityEntry

public static string LogMessageDbEntityValidationException(DbEntityValidationException ex) 
{ 
    StringBuilder error = new StringBuilder(); 

    error.AppendLine("Validation Error details for DbEntityValidationException throw: "); 

    foreach (var validationErrors in ex.EntityValidationErrors) 
    { 
     foreach (var validationError in validationErrors.ValidationErrors) 
     { 
     error.AppendLine(string.Format("Property: {0} , Error: {1}", 
          validationError.PropertyName, validationError.ErrorMessage)); 
     } 
    } 

    return error.ToString(); 
} 

ho incontrato un problema cercando di creare unità di prova, in particolare non riesco a creare un DbEntityValidationResult perché richiedeva un esempio di DbEntityEntry, che non ha un costruttore pubblico.

Qui è rotto Unità di prova, non riesce a creare il DbEntityEntry:

public void LogMessageDbEntityValidationExceptionTest() 
{ 
    string errorMessage = "Unit Test Error Message"; 
    string expected = "Not valid data."; 
    List<DbEntityValidationResult> entityValidationResults = new List<DbEntityValidationResult>(); 
    List<DbValidationError> errorList = new List<DbValidationError>(); 
    DbEntityValidationException ex; 

    errorList.Add(new DbValidationError("TestProperty", expected)); 

    entityValidationResults.Add(new DbEntityValidationResult(new System.Data.Entity.Infrastructure.DbEntityEntry(), errorList)); 

    ex = new DbEntityValidationException(errorMessage, entityValidationResults); 
    string actual = Common.LogMessageDbEntityValidationException(ex); 

    Assert.IsTrue(actual.Contains(expected)); 
} 

nota, DbEntityEntry non implementa un'interfaccia, quindi non posso usare un finto/falso.

+0

Hai mai trovato una soluzione a questo problema? – user1535568

risposta

1

Alcuni framework di simulazione come Moq do reindirizzamento del metodo consentono di simulare classi senza interfacce. Analogamente a http://www.codenutz.com/unit-testing-mocking-base-class-methods-with-moq/

Detto questo, non è una buona pratica di programmazione, poiché il codice di test verrà reso dipendente da tale framework per sempre e si perderanno alcuni dei vantaggi di progettazione dei test unitari.

Quello che puoi fare è scrivere una classe proxy per avvolgere il tuo oggetto non testabile e aggiungere un'interfaccia su di esso, quindi usi la classe proxy ogni volta che useresti la classe normale.

+1

Sfortunatamente l'oggetto non testabile è sepolto nel codice EF. Dovrei scrivere un wrapper attorno a troppi codici. – Josh

+0

Si può anche provare a usare l'inizializzatore dell'oggetto per chiamare il costruttore privato predefinito per l'oggetto. http://msdn.microsoft.com/en-us/library/bb397680.aspx Con quello detto usando Moq dovresti essere in grado di usare il framework per farlo. –