2010-06-17 3 views
2

Я приступаю к первому путешествию, основанному на тестах, на C#. Для начала я использую MSTest и Rhino.Mocks. Я пытаюсь написать свои первые модульные тесты против моего ICustomerRepository. Кажется утомительным для нового метода Customer для каждого метода тестирования. В ruby-on-rails я бы создал файл семян и загрузил клиента для каждого теста. Кажется логичным, что я мог бы поставить эту плиту котла Customer в свойство тестового класса, но тогда я рискну его модифицировать. Каковы мои возможности для упрощения этого кода?Seeding repository Rhino Mocks

[TestMethod] 
public class CustomerTests : TestClassBase 
{ 
    [TestMethod] 
    public void CanGetCustomerById() 
    { 
     // arrange 
     var customer = new Customer() 
     { 
      CustId = 5, 
      DifId = "55", 
      CustLookupName = "The Dude", 
      LoginList = new[] { 
       new Login { LoginCustId = 5, LoginName = "tdude" } } 
     }; 

     var repository = Stub<ICustomerRepository>(); 

     // act 
     repository.Stub(rep => rep.GetById(5)).Return(customer); 

     // assert 
     Assert.AreEqual(customer, repository.GetById(5)); 
    } 

    [TestMethod] 
    public void CanGetCustomerByDifId() 
    { 
     // arrange 
     var customer = new Customer() 
     { 
      CustId = 5, 
      DifId = "55", 
      CustLookupName = "The Dude", 
      LoginList = new[] { 
       new Login { LoginCustId = 5, LoginName = "tdude" } } 
     }; 

     var repository = Stub<ICustomerRepository>(); 

     // act 
     repository.Stub(rep => rep.GetCustomerByDifID("55")).Return(customer); 

     // assert 
     Assert.AreEqual(customer, repository.GetCustomerByDifID("55")); 
    } 

    [TestMethod] 
    public void CanGetCustomerByLogin() 
    { 
     // arrange 
     var customer = new Customer() 
     { 
      CustId = 5, 
      DifId = "55", 
      CustLookupName = "The Dude", 
      LoginList = new[] { 
       new Login { LoginCustId = 5, LoginName = "tdude" } } 
     }; 

     var repository = Stub<ICustomerRepository>(); 

     // act 
     repository.Stub(rep => 
      rep.GetCustomerByLogin("tdude")).Return(customer); 

     // assert 
     Assert.AreEqual(customer, repository.GetCustomerByLogin("tdude")); 
    } 
} 

Тест Базовый класс

public class TestClassBase 
{ 
    protected T Stub<T>() where T : class 
    { 
     return MockRepository.GenerateStub<T>(); 
    } 
} 

ICustomerRepository и IRepository

public interface ICustomerRepository : IRepository<Customer> 
{ 
    IList<Customer> FindCustomers(string q); 
    Customer GetCustomerByDifID(string difId); 
    Customer GetCustomerByLogin(string loginName); 
} 

public interface IRepository<T> 
{ 
    void Save(T entity); 
    void Save(List<T> entity); 
    bool Save(T entity, out string message); 
    void Delete(T entity); 
    T GetById(int id); 
    ICollection<T> FindAll(); 
} 

ответ

2

Я бы извлечь код для создания клиента в метод. Вы можете вызвать это из своих методов тестирования, и если вы назовете его чем-то вроде SetUpCustomerForRepository, тогда он предоставит некоторую документацию о том, что вы делаете.

Вот пример, основанный на образце:

private Customer SetUpCustomerForRepository() 
{ 
    return new Customer() 
    { 
     CustId = 5, 
     DifId = "55", 
     CustLookupName = "The Dude", 
     LoginList = new[] { 
      new Login { LoginCustId = 5, LoginName = "tdude" } } 
    }; 
} 

Вы также мог бы назвать его из теста установить метод, но я предпочитаю делать это в методе испытаний, так что люди, глядя на тесте знать, что настроено для теста.

Что касается вашего беспокойства по поводу его модификации .... если это произойдет, тогда ваши тесты потерпят неудачу, и вы узнаете об этом.

+0

Я думаю, что я знаю, что вы говорите, но не могли бы вы поместить его в код ради потомства? :) – ahsteele

+0

Добавил метод создания клиента, а затем заметил, что ваши тесты используют разные условия для заглушки в Rhino Mocks, поэтому, вероятно, лучше оставить их в тесте (таким образом, проще видеть, что вы тестируете) , – ckramer

2

Вы можете вакцинировать себя от изменений тестового клиента, изменяя ваши окурки и утверждение, чтобы использовать его свойство:

[TestMethod] 
public void CanGetCustomerByDifId() { 

    var customer = this.TestCustomer; 

    var repository = Stub<ICustomerRepository>(); 

    repository.Stub(rep => rep.GetCustomerByDifID(customer.DifID)) 
       .Return(customer); 

    Assert.AreEqual(customer, repository.GetCustomerByDifID(customer.DifID)); 
} 
3

модульных тестов не имеют никакой реальную ценность, потому что они просто тестирование Rhino. Mocks.

Что вы хотите сделать, это использовать Rhino.Mocks для создания заглушки ICustomerRepository для других компонентов/служб, которым необходим ICustomerRepository. Таким образом, вместо использования CustomerRepository, который ведет переговоры с базой данных или каким-либо плоским файлом, вы будете использовать обрезанные ICustomerRepository и Rhino.Mocks, которые позволят вам настроить предопределенные ответы на определенные методы, что позволит вам протестировать ваши службы в изоляция.

+1

+1 - красиво положить. –