0

私はLINQ-to-SQLASP.NET MVC 4 を使用しています。現時点では、実際のデータベースに接続するリポジトリ レイヤーがあります。これは、単体テストを行う場合にはあまり適していません。

また、リポジトリ レイヤーには決してロジックがあってはならないためLINQ DataContext、モックDataContextまたは実際の と通信するサービス レイヤーを作成できるように、 をモックしDataContextます。

LINQ DataContext クラスが を継承していることがわかりDataContextますが、インターフェイスがないため、実際にモックすることはできません。また、 DataContext がTable<>クラスを使用し、 interface が存在することもわかりますITable。おそらくそれをモックできます。また、私LINQ DataContextは部分クラスなので、何らかの方法でそれを操作できますか?

これをグーグルで検索すると、すべての記事は 2008 年のものであり、古くなっています。誰かが私を正しい適切な方向に導くことができますか?

これが私がやりたいことの例です。コントローラーごとに個別のサービス クラスを用意します。

public class MyServiceClass
{
    IDataContext _context;

    // Constructors with dependency injection

    public MyServiceClass()
    {
        _context = new MyRealDataContext();
    }

    public MyServiceClass(IDataContext ctx)
    {
        _context = ctx;
    }

    // Service functions

    public IEnumerable<ModelClass> GetAll()
    {
        return _context.ModelClass;
    }

    public ModelClass GetOne(int id)
    {
        return _context.Where(s => s.ID == id).SingleOrDefault();
    }
}
4

1 に答える 1

1

Linq-to-Sql は .NET 4+ でも引き続きサポートされていますが、Entity Framework が優先されて押し戻されました。それがおそらく、ほとんどが古い記事を見つけている理由です。

とにかく最善の方法は、アプリケーションで使用される独自の DataAccess レイヤー インターフェイスを作成することです。次に、本番用に linq-to-sql を使用するそのインターフェイスの実装と、単体テスト用のモック実装を使用できます。

依存性注入を使用して、実際の実装クラスをインスタンス化します。

モック実装を作成するには、手動で行うか (IDataContext インターフェイスを実装するが、ハードコードされたデータを返すテスト プロジェクトでクラスを作成する)、またはそこにあるモック フレームワークの 1 つを使用します。

私はそれらのすべてを使用したわけではありませんが、moqは非常に良かったです. Microsoft は現在、Visual Studio 2012 にFakesと呼ばれるフレームワークを持っています。

moqの使用例

var expectedResultList = new List<ModelClass>(){ ... };
var mockDataContext = new Mock<IDataContext>();
mock.Setup(c => c.GetAll()).Returns(expectedResultList);

MyServiceClass service = new MyServiceClass(mockDataContext.Object);
var list = service.GetAll();
Assert.AreEqual(expectedResultList, list);

このコードでは、GetAll メソッドが呼び出されたときに期待されるリストを返すように、モック オブジェクトを設定します。このようにして、データ アクセスからのさまざまなリターンに基づいて、ビジネス ロジックを簡単にテストできます。

IDataContext の例

public interface IDataContext<T>
{
   IEnumerable<T> GetAll();
   T GetById(int id);
   int Save(T model);
}

public class LinqToSqlDataContext<T> : IDataContext<T>
{
    private DataContext context = new DataContext();

    public IEnumerable<T> GetAll()
    {
         // query datacontext and return enumerable
    } 

    public T GetById(int id)
    {
         // query datacontext and return object
    }

    public int Save(T model)
    {
        // save object in datacontext
    }
}

public class MyFirstServiceClass
{
     private IDataContext<MyClass> context;
     public MyFirstServiceClass(IDataContext<MyClass> ctx)
     {
        this.context = ctx;
     }
     ....
}
public class MySecondServiceClass
{
     private IDataContext<MySecondClass> context;
     public MyFirstServiceClass(IDataContext<MySecondClass> ctx)
     {
        this.context = ctx;
     }
     ....
}
于 2013-06-05T09:20:14.533 に答える