2

Я новичок в проекте, который я должен расширить, поэтому я решил использовать TDD для быстрого распознавания любых проблем системы, которые я не совсем понимаю.Как модульный тест DBService, который использует Servicestack Funq IOC

Существует один класс под названием DBService, который «инкапсулирует» весь доступ к db. Например, существует один метод, называемый getAllCustomers, который возвращает список Customers. Это будет выглядеть примерно так (это просто пример для лучшего понимания):

public class DBService 
{ 
    public IDbConnectionFactory DBFactory { 
     get { return DI.Container.Resolve<IDbConnectionFactory>(); } 
    } 

    public List<Customer> GetAllCustomers() 
    { 
     try 
     { 
      using (var connection = DBFactory.OpenDbConnection()) 
      { 
       var dbResult = connection.Select<Customer>(); 
       // code ommitted 
      } 
     } 
     catch (Exception e) 
     { 
      // code ommitted 
     } 
    }  
} 

Другая проблема заключается в том, что при запуске (в ServiceStack AppHost.Configure) все таблицы созданы, если они не существуют, и для некоторых таблицы, если они существуют, некоторые столбцы и т. д. добавляются (вероятно, изменения, которые были добавлены позже)

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

  1. Я не могу вводить любой DBFactory поскольку добытчик является частным
  2. AFAIK я не могу использовать строку :memory: соединения для OrmLiteConnectionFactory, потому что я использую ServiceStack 3.9.74

Так что мои варианты здесь ?

ответ

2

Избегайте использования антивируса Service Locator и используйте вместо него инъекцию конструктора. Старайтесь избегать использования контейнеров DI непосредственно в зависимых классах. Он плотно соединяет ваши классы с проблемами, которые там не принадлежат, и затрудняют тестирование классов в изоляции.

public class DBService { 
    private readonly IDbConnectionFactory connectionFactory; 

    public DBService(IDbConnectionFactory connectionFactory) { 
     this.connectionFactory = connectionFactory; 
    } 

    public IDbConnectionFactory DBFactory { get { return connectionFactory; } } 

    public List<Customer> GetAllCustomers() { 
     try { 
      using (var connection = DBFactory.OpenDbConnection()) { 
       var dbResult = connection.Select<Customer>(); 
       //... code omitted for brevity 
      } 
     } catch (Exception e) { 
      //... code omitted for brevity 
     } 
    } 
} 

Оба Select<T> и OpenDbConnection выглядят как методы расширения. Я бы посоветовал проверить, что их ожидает, и издеваться над этим поведением.

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

public interface IDbService { 
    IDbConnectionFactory DBFactory { get; } 
    List<Customer> GetAllCustomers(); 
} 

и имеют реализацию наследуют

public class DbService : IDbService { 
    //... code removed for brevity 
} 

и убедитесь, что зарегистрировать все с контейнером IoC.

+0

Да, я согласен, что анти-шаблон-сервис-локатор - это то, что я должен стараться избегать. Я просто подумал, что есть простой способ без большого количества рефакторинга. – zlZimon

+0

Это дело с [Технический долг] (https://www.google.com/search?q=technical+debt). Он всегда звонит в кредит. – Nkosi

 Смежные вопросы

  • Нет связанных вопросов^_^