Specifica query in Test unità

2

Durante la scrittura dei test delle unità, dovrei specificare la query che verrà eseguita per interagire con il database?

Posso vedere entrambi i lati di questo. Da un lato, voglio assicurarmi che la query che specifichi venga eseguita. Ma posso rendere il test più fragile a causa della formattazione della query.

Modifica Fondamentalmente il codice sarebbe un oggetto mapper che interagisce con il livello db. Ma mi chiedo quanto sia necessario specifico nelle mie interazioni con un oggetto Db.

Modifica

Come voglio prendere in giro eventuali dipendenze esterne ai miei oggetti quando sto prendendo in giro la mia connessione al database. Devo specificare la query che verrà eseguita.

Ad esempio:

testGettingUsers() {
    $mockDb = $this->getMockBuilder('My_DB_Connection')
         ->setMethods(array('query'))
         ->getMock();

    $mockDb->expects($this->once())
         ->method('query')
         ->with('SELECT id, name FROM USERS WHERE name = foo')
         ->will($this->returnValue($dbReturn));

Qui ho specificato la mia query come parametro con cui chiamerò la mia connessione DB. È necessario?

    
posta Schleis 29.01.2013 - 17:39
fonte

1 risposta

3

Ciascuna delle tue classi dovrebbe avere una responsabilità specifica (cosa fa) e dovrebbe fare solo quella cosa (una singola responsabilità) e dovrebbe farlo bene. Il tuo test dovrebbe garantire che l'oggetto in questione faccia ciò che dovrebbe.

Per quanto riguarda un oggetto mapper, siamo preoccupati che possa mappare correttamente da un'origine dati (non ci interessa quale sia l'origine sottostante) per un dato oggetto (ad esempio un oggetto dominio). Con questo in mente dovrebbe essere sicuro assumere che la query effettiva per la tua mappatura è contenuta all'interno dei metodi sul tuo oggetto mapper.

public class CustomerMapper {
  private DatabaseObject _myDb;
  public Customer FindCustomerWithId(int id){
    return _myDb.Query("SELECT * FROM CUSTOMERS WHERE ID = " + id).FirstOrDefault();
  }
}

In questo caso il test dell'unità testerebbe semplicemente il metodo FindCustomerWithId e non si preoccupa della query fornita.

public class CustomerMapperTests {
  [Test]
  public void test_finding_a_customer_by_id() {
     var systemUnderTest = new CustomerMapper();
     var customer = CustomerMapper.FindCustomerWithId(5);
     customer.ShoudlNotBeNull(); // Assertion
  }
}

Ora se dovessimo testare la classe DatabaseObject allora avrebbe senso testare le query effettive per garantire che detta classe le gestisse come previsto.

public class DatabaseObjectTests {
  [Test]
  public void test_that_it_can_handle_a_count_query(){
    var systemUnderTest = new DatabaseObject();
    var numberOfCustomers = systemUnderTest.Query<int>("SELECT COUNT(*) FROM CUSTOMERS);
    numberOfCustomers.Should().Be(10);
  }
}

Modifica Per affrontare l'idea di deridere l'oggetto del database durante il test CustomerMapper, non mi occuperei nemmeno di query o SQL. Qualcosa sulla falsariga di:

public void test_finding_a_customer(){
  var mock = new Mock<DatabaseObject>();
  mock.Setup(m => m.Query(It.IsAny<string>()).Returns(new Customer { Id = 5 });
  var systemUnderTest = new CustomerMapper(mock.Object);
  var customer = CustomerMapper.FindCustomerWithId(5);
  customer.ShoudlNotBeNull(); // Assertion
}
    
risposta data 29.01.2013 - 18:22
fonte

Leggi altre domande sui tag