2

私は拡張するべきプロジェクトには新しく、完全に理解できないシステムの問題をTDDで迅速に認識することにしました。Servicestack Funqを使用するDBServiceのテスト方法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. 私はServiceStack 3.9.74

を使用していますので、私はそう私のオプションはここで何しているOrmLiteConnectionFactoryため:memory:接続文字列を使用することはできません私の知る限りゲッターが

  • プライベートですので、私はどんな DBFactoryを注入することはできません?

    答えて

    2

    サービスロケータのアンチパターンを避け、代わりにコンストラクタインジェクションを使用します。依存クラスで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

    関連する問題