SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

C#で始めるテスト駆動開発入門

TDDでデータベースと付き合う方法

C#で始めるテスト駆動開発入門(7)

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード CsTdd07.zip (474.5 KB)

DbCommandにパラメーターをセットする手続きを分離する

 ここまでを使って製品コードをリファクタリングしてみると、cmd.ParametersをセットしているところもDbCommandHelperに持っていきたくなります。

テストコード: [改2] DbCommandHelperAddStringParameter()を実装するテスト
[TestCase]  //製品コード: AddStringParameter()メソッドを実装
public void AddStringParameterTest() {
  using (DbCommandHelper helper = new DbCommandHelper())
  using (DbCommand cmd = helper.CreateCommand(cmdText)) {

    helper.AddStringParameter(cmd, "@p1", "param1");

    Assert.AreEqual("@p1", cmd.Parameters[0].ParameterName);
    Assert.AreEqual("param1", cmd.Parameters[0].Value);
  }
}

 これでDbCommandHelperの完成です。

製品コード: [改2] 完成したDbCommandHelperクラス
public class DbCommandHelper : IDisposable {

  private SqlCeConnection _connection;

  public SqlCeConnection Connection {
    get {
      if (_connection == null && disposed == false) {
        _connection = DbConnectionProvider.Connection;
        _connection.Open();
      }
      return _connection; 
    }
  }

  public DbCommand CreateCommand(string commandText) {
    var cmd = new SqlCeCommand(commandText);
    cmd.Connection = Connection;
    return cmd;
  }

  public void AddStringParameter(DbCommand cmd, string paramName, string parameter) {
    var p1 = cmd.CreateParameter();
    p1.ParameterName = paramName;
    p1.DbType = System.Data.DbType.String;
    p1.Value = parameter;
    cmd.Parameters.Add(p1);
  }


  // Dispose パターンの実装のスケルトンはMSDNのサンプルからコピペする
  public void Dispose() {
    Dispose(true);
    GC.SuppressFinalize(this);
  }
  private bool disposed = false;
  protected virtual void Dispose(bool disposing) {
    if (!this.disposed) {
      if (disposing) {
        //↓ここだけはテストファーストで書く
        if (_connection != null) {
          _connection.Dispose();
          _connection = null;
        }
      }
      disposed = true;
    }
  }
}

 検索するメソッドは、リファクタリングして次のようになりました。以前の「とりあえず実装してみた」製品コードと比べてみてください。

製品コード: [改2] SqlServerCeに依存しなくなった前方一致で姓名を検索する()メソッド
public static IList<Customer> 前方一致で姓名を検索する(string head) {
  var list = new List<Customer>();

  if (string.IsNullOrWhiteSpace(head))
    return list;

  using(DbCommandHelper helper = new DbCommandHelper()){

    var cmdText =
@"SELECT  Country, [Company Name], [Customer ID], [Contact Name]
FROM      Customers
WHERE     ([Contact Name] LIKE @p1) OR ([Contact Name] LIKE @p2)";

    using (DbCommand cmd = helper.CreateCommand(cmdText)) {
      helper.AddStringParameter(cmd, "@p1", head + "%");
      helper.AddStringParameter(cmd, "@p2", "% " + head + "%");
      using (DbDataReader reader = cmd.ExecuteReader()) {
        while (reader.Read()) {
          var customer = new Customer() {
            Country = reader.GetString(0),
            CompanyName = reader.GetString(1),
            CustomerID = reader.GetString(2),
            ContactName = reader.GetString(3),
          };
          list.Add(customer);
        }
      }
    }
  }
  return list;
}

次のページ
DbCommandの取扱いも分離する

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
C#で始めるテスト駆動開発入門連載記事一覧

もっと読む

この記事の著者

biac(ばいあっく)

HONDA R&Dで自動車の設計をやっていた機械屋さんが、技術の進化スピードに魅かれてプログラマーに。以来30年ほど、より良いコードをどうやったら作れるか、模索の人生。わんくま同盟の勉強会(名古屋)で、よく喋ってたりする。2014/10~2019/6 Microsoft MVP (Windows Devel...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6783 2012/10/30 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング