2

JustMockを使用すると、次のように Linq to SQL のリストを使用して DataContext テーブルを簡単にモックできます。ここでは、ReturnsCollection() を介して IEnumerable が各 DataContext のテーブルの代わりになり、偽のデータをプラグインできます。

[TestMethod]
public void ShouldGetManagersByHireDate()
{
   var context = Mock.Create<MyDataContext>();
   Mock.Arrange(()=> context.Employees).ReturnsCollection(GetFakeEmployees());
   Mock.Arrange(() => context.Managers).ReturnsCollection(GetFakeManagers());

   var repository = new EmployeeRepository(context);
   var managers = repository.GetManagersByHireDate(new DateTime(2002, 1, 1), DateTime.Now);

   Assert.AreEqual(1, managers.Count());
   Assert.AreEqual(1, managers.FirstOrDefault().ID);
}

private IEnumerable<Employee> GetFakeEmployees()
{
    return new List<Employee> { 
        new Employee { ID = 1, HireDate = new DateTime(2004, 12, 1) }, 
        new Employee { ID = 2, HireDate = new DateTime(2006, 7, 1) }, 
        new Employee { ID = 3, HireDate = new DateTime(2009, 3, 1) } 
    };
}

private IEnumerable<Manager> GetFakeManagers()
{
    return new List<Manager> { 
        new Manager { ID = 1 }
    };
}

そして、これがテスト対象のメソッドになります。

public IQueryable<Employee> GetManagersByHireDate(DateTime start, DateTime end)
{
    return  from e in context.Employees
            join m in context.Managers on e.ID equals m.ID
            where e.HireDate >= start && e.HireDate <= end
            select e;
}

できれば FakeItEasy で、Linq to SQL をテストする目的でIEnumerable<T>代わりに使用できる同じ魔法を実行する方法を探しています。Table<T>

4

2 に答える 2

2

Linq to SQL は、オープン ソース ツールを使用してテストするのが最も簡単なことではありません。うまくいけば、このアプローチがうまくいくかもしれません。

FakeItEasy には、ITable をモックアウトして IEnumerable を返すことができる JustMock の ReturnCollection とまったく同じようなメソッドがありません。選択肢の 1 つは、ここに示すような MockableTable を作成することです。次に、テーブルにデータを入力するには、次のようなものがあります

private ITable<Employee> GetFakeEmployees() {
    List<Employee> sampleData = /* fill it up with employees */
    var employeeTable = new MockableTable<Employee>(null, sampleData.AsQuerable());                 
    return employeeTable;
}

また、FakeItEasy は、具象クラスの非仮想プロパティであるため、DataContext の Employees プロパティをインターセプトしません。単純なカスタム基本クラスを作成し、そこから MyDataContext クラスを直接派生させることができます。

public abstract class CustomDataContext : DataContext, ICustomDataContext {
}

public interface ICustomDataContext {
    ITable<Employee> { get; }
}

ここでの主なポイントは、モックのインターフェイスを活用することです。次に、テストメソッドでは、次のようになります。

[TestMethod]
public void ShouldGetManagersByHireDate() {
   var context = A.Fake<ICustomDataContext>();
   A.CallTo(()=> context.Employees).Returns(GetFakeEmployees());


   var repository = new EmployeeRepository(context);
   var managers = repository.GetManagersByHireDate(new DateTime(2002, 1, 1), DateTime.Now);

   Assert.AreEqual(1, managers.Count());
   Assert.AreEqual(1, managers.FirstOrDefault().ID);
}

私は実際にこれをコンパイルしていませんが、コンセプトは安定しているはずです。抽象化に依存することで、コードをよりテストしやすくなり、モックしやすくなります。

これが多少役立つことを願っています。

于 2013-02-22T21:34:57.713 に答える
2

FakeItEasy を使用してこれを行った方法は、インターフェイスを DataContext に追加し、それをリポジトリの依存関係として使用することです。例えば

public interface IMyDataContext : IDisposable
{
    IQueryable<Employee> Employees { get; }

    // etc.
}

public partial class MyDataContext: IMyDataContext
{
    IQueryable<Message> IMyDataContext.Employees
    {
        get { return this.Employees; }
    }

    // etc.
}

public class EmployeeRepository
{
    public EmployeeRepository(IMyDataContext context)
    {
        // etc.
    }
}

そして私のテストでは:

var context = A.Fake<IMyDataContext>();
A.CallTo(() => context.Employees).Returns(new[] { new Employee { Name = "John", Name = "Fred" }.AsQueryable());
var repository = new EmployeeRepository(context)

周囲への配慮は必要ないと思いますITable

于 2013-04-02T09:37:54.727 に答える