2012-05-26 11 views
7

Sto usando PetaPoco sul mio progetto corrente come un micro ORM e devo dire che mi piace. Tuttavia, mi sono trovato alle prese con semplice scenario - servizi di test unità che utilizzano PetaPoco.DatabaseCome servizio di unit test che utilizza PetaPoco.Database

public class MyService : IMyService 
{ 
    private readonly PetaPoco.Database _database; 

    public MyService(PetaPoco.Database database) 
    { 
     _database = database; 
    } 

    public void SaveSomething(MyObject myObject) 
    { 
     //...custom logic 
     _database.Save(myObject); 
    } 
} 

Sto usando IOC (Castle.Windsor) per l'iniezione di entrambi IMyService e PetaPoco.Database ovunque sia necessario.

Ora, quando provo a unità di testare il mio servizio non posso correttamente finta stub PetaPoco.Database al fine di verificare che il metodo Salva stata correttamente invocata. Sto usando NUnit e Rhino.Mocks per test di unità e derisione.

[TestFixture] 
public class MyServiceTests 
{ 

    private PetaPoco.Database _database; 

    [SetUp] 
    public void SetUp() 
    { 
     _database = MockRepository.GenerateMock<Database>(""); 
    } 

    [Test] 
    public void ShouldProperlySaveSomething() 
    { 
     //Arrange 
     var myObject = new MyObject(); 
     _database.Expect(db => db.Save(Arg<MyObject>.Is.Anything)); 
     var myService = new MyService(_database); 

     //Act 
     myService.SaveSomething(myObject); 

     //Assert 
     _database.VerifyAllExpectations(); 
    } 

} 

Mi rendo conto che questo può essere risolto se estraggo un'interfaccia da PetaPoco.Database e fare il beffardo contro di esso, o virtualizzando i metodi di PetaPoco che voglio prendere in giro, ma il punto è che io non voglio apportare modifiche a PetaPoco affatto.

È fattibile?

risposta

4

La mia filiale situata qui: https://github.com/schotime/PetaPoco ha già un'interfaccia definita per la classe Database.

Inoltre c'è il mio nuovo Fork https://github.com/schotime/NPoco o NPoco su nuget che ha la stessa api.

Vorrei usare uno di questi. ;)

+0

Ottimo lavoro @Schotime, questo è esattamente ciò di cui avevo bisogno! Sono curioso però, hai provato a creare richieste di pull alla base di codice originale? – ljubomir

+0

Molte volte, ma ora ho molte più funzionalità come parte della libreria, con molte correzioni di bug quindi sono quasi due separate ora. – Schotime

+0

Sono supportate tutte le funzionalità di petapoco (come i modelli) o mancano le cose? Sembra che anche la tua forcella faccia ciò che questo plugin fa PetaPoco.RelationExtensions. Stai usando lo stesso codice?Mi chiedo come tu non veda di avere alcuna documentazione su alcune delle tue funzionalità, quindi spero di poter utilizzare esempi da altri plugin esistenti. – chobo2

1

Stai già astrarre le interazioni con PetaPoco.Database utilizzando le interazioni di IMyService, quindi perché hai bisogno di un'altra astrazione? Con il tuo attuale approccio dovresti essere in grado di testare le interazioni con il database usando IMyService, ad es.

public class AuthenticationService 
{ 
    private IMyService myService; 

    public AuthenticationService(IMyService service) 
    { 
     ... 
    } 

    public void Authenticate(string username, string password) 
    { 
     var user = myService.GetUser(username); // <-- Hits the database 
    } 
} 

e per testarlo basta prendere in giro le interazioni utilizzando un simulato/stub di IMyService.

Ora, per quanto riguarda la soluzione originale, se i metodi pubblici PetaPoco non sono virtuali, lo forcherei, correggerò il codice e invierò loro una richiesta pull. Altrimenti, il tuo approccio mi sta bene.

+1

Grazie per la risposta @Hadi. Il punto che sto ponendo questa domanda sta nel fatto che voglio testare la logica di business di MyService da sola, cioè non voglio colpire il database, e allo stesso tempo voglio assicurarmi che le chiamate al database vengano attivate tramite PetaPoco. Per come la vedo io, questo è possibile solo deridendo ** PetaPoco.Database **. – ljubomir

+0

Forcella il codice, d'altra parte mi sembra una buona soluzione, potrei provarlo. – ljubomir