0

私がテストしている方法があります。このメソッドのコンストラクターは、その基本クラスのコンストラクターを呼び出し、次にその基本クラスのコンストラクターでいくつかのメンバーを設定し、メソッドを実行してデータベースからデータをフェッチし、データベース値の一部をより多くのメンバーに設定します (すべてコンストラクターで行われます)。 )。

元のメソッドをテストするために、コンストラクターでデータベースへの呼び出しを削除し、リファクタリングしてメンバーを設定するだけにすれば、テストでコンストラクターを簡単に実行して、渡されたインターフェイスをスタブ化できます。 (この場合は1)または、データベース呼び出しを行うコンストラクターのメソッドをシムアウトしようとする必要がありますか??

    // method under test
    public override DateTime ResolveDate(ISeries comparisonSeries, DateTime targetDate)
    {
        switch (comparisonSeries.Key)
        {
            case SeriesKey.SomeKey1:
            case SeriesKey.SomeKey2:
            case SeriesKey.SomeKey3:
            case SeriesKey.SomeKey4:
            case SeriesKey.SomeKey5:
                return DateHelper.PreviousOrCurrentQuarterEnd(targetDate);
            default:
                break;
        }

        return base.ResolveDate(comparisonSeries, targetDate);
    }
// constructor
    public ReportForm(SeriesKey key, IAppCache cache)
        : base(key, cache)
    {
        //sets some base members here.
    }

 // base class that the constructor calls
 public abstract class SeriesBase : ISeries
{
    #region variables

    protected IAppCache clientCache;
    // other members below

        // base constructor
public SeriesBase(SeriesKey key, IAppCache cache)
    {
        this.key = key;
        this.clientCache = cache;
        this.infoPack = new SeriesInfo();
        this.InitalizeSeries();
    }
private void InitalizeSeries()
    {
        Dictionary<string, object> qInfoSQL = new Dictionary<string, object>();
        qInfoSQL.Add("@SeriesID", this.key.ToIntString());

        DBServiceResult result = this.clientCache.DBService.FetchFromDB("spSeriesInit", CommandType.StoredProcedure, qInfoSQL);

        if (result.Failed)
            throw new NotImplementedException("whoat");

        this.SetPublishTimeLag(result.XMLResult.Elements("tbl0").FirstOrDefault());
        this.AddFormView(result.XMLResult.Elements("tbl1").FirstOrDefault());
        this.AddPresentation(result.XMLResult.Elements("tbl2").DefaultIfEmpty(null).FirstOrDefault());

        this.SetBridge();
        this.InitializeGenerics();

    }

this.clientCache.DBService.FetchFromDB(...) メソッドは、メソッド FetchFromDB を呼び出す別のインターフェイス DBService を呼び出しています。この fetchfromDb メソッドは QSL サーバーに行き、データセットを取得します。

これが私のテスト方法です。

public void TestResolveDate()
    {
        //using (ShimsContext.Create())
        //{
        //    Stat.Pi.Data.Fakes.ShimAuthenticator
        //}

        var appCache = new Fakes.StubIAppCache();
        appCache.DBServiceGet = DbServiceGet;


        ReportFORM formReport = new ReportForm(SeriesKey.SomeKey1, appCache);

        var series = new Fr Fakes.StubISeries();

        DateTime date = formReport.ResolveDate(series, DateTime.Now);


        //Assert.
    }
private IDBService DbServiceGet()
    {
        Dictionary<string, object> dict = new Dictionary<string, object>();
        dict.Add("@SeriesID", "50");

        var service = new Fakes.StubIDBService();
        service.FetchFromUnicornStringCommandTypeDictionaryOfStringObject = (s, type, arg3) => dict 
        return service;

    }
4

1 に答える 1

0

1) Henk Holterman が言うように、コンストラクターはデータベースを呼び出すべきではありません。これにより、カップリングが増加し、凝集力が低下します。

2) 探しているデザイン パターンは、Factory パターンと呼ばれます - http://en.wikipedia.org/wiki/Factory_method_pattern - これは、構築、初期化、および作成を分離します。一方、オブジェクトの永続性を処理するヘルパー クラスまたはハンドラー クラスを導入することもできます。

3) コードのリファクタリングは管轄外である可能性があるため、テストを実行するためにデータベース アクセス スタブを配置することは合理的です。ただし、個人的には、永続化ヘルパー クラスを導入して、新しく作成されたオブジェクトをデータベースの値にバインドすることをお勧めします。

于 2013-05-31T17:43:21.640 に答える