1

私は単体テストにかなり慣れていないので、アプリケーションの汎用リポジトリの単体テストに関していくつか問題があります。ASP.NET MVC アプリケーションに作業単位パターンを実装しました。私のクラスは次のようになります。

public class UnitOfWork : IUnitOfWork
{
    private bool disposed = false;

    private IGenericRepository<Shop> _shopRespository;

    public UnitOfWork(PosContext context)
    {
        this.Context = context;
    }

    public PosContext Context { get; private set; }

    public IGenericRepository<Shop> ShopRepository
    {
        get
        {
            return this._shopRespository ?? (this._shopRespository = new GenericRepository<Shop>(this.Context));
        }
    }

    public void SaveChanges()
    {
        this.Context.SaveChanges();
    }

    public void Dispose()
    {
        this.Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                this.Context.Dispose();
            }
            this.disposed = true;
        }
    }
}

public class PosContext : DbContext, IPosContext
{
    public DbSet<Shop> Shops { get; private set; }
}

public class GenericRepository<T> : IGenericRepository<T>
    where T : class
{
    private readonly PosContext context;
    private readonly DbSet<T> dbSet;

    public GenericRepository(PosContext context)
    {
        this.context = context;
        this.dbSet = context.Set<T>();
    }

    public virtual IEnumerable<T> Get(
        Expression<Func<T, bool>> filter = null,
        Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
        string includeProperties = "")
    {
        IQueryable<T> query = this.dbSet;

        if (filter != null)
        {
            query = query.Where(filter);
        }

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
        {
            return orderBy(query).ToList();
        }
        else
        {
            return query.ToList();
        }
    }

    public virtual T Find(object id)
    {
        return this.dbSet.Find(id);
    }

    public virtual void Add(T entity)
    {
        this.dbSet.Add(entity);
    }

    public virtual void Remove(object id)
    {
        T entityToDelete = this.dbSet.Find(id);
        this.Remove(entityToDelete);
    }

    public virtual void Remove(T entityToDelete)
    {
        if (this.context.Entry(entityToDelete).State == EntityState.Detached)
        {
            this.dbSet.Attach(entityToDelete);
        }
        this.dbSet.Remove(entityToDelete);
    }

    public virtual void Update(T entityToUpdate)
    {
        this.dbSet.Attach(entityToUpdate);
        this.context.Entry(entityToUpdate).State = EntityState.Modified;
    }

NUnit と FakeItEasy を使用して単体テストを作成しています。セットアップ関数で、偽の PosContext オブジェクトを使用して UnitIfWork オブジェクトを作成します。次に、コンテキストにいくつかの Shop オブジェクトを設定します。

[SetUp]
public void SetUp()
{
    this.unitOfWork = new UnitOfWork(A.Fake<PosContext>());
    this.unitOfWork.ShopRepository.Add(new Shop() { Id = 1, Name = "Test name1" });
    this.unitOfWork.ShopRepository.Add(new Shop() { Id = 2, Name = "Test name2" });
    this.unitOfWork.ShopRepository.Add(new Shop() { Id = 3, Name = "Test name3" });
    this.unitOfWork.ShopRepository.Add(new Shop() { Id = 4, Name = "Test name4" });
    this.unitOfWork.ShopRepository.Add(new Shop() { Id = 5, Name = "Test name5" });
    this.Controller = new ShopController(this.unitOfWork);
}

GenericRepository の Find メソッドをテストすると、問題なく動作します。正しい Shop オブジェクトが返され、正常に動作していると断言できます。

    [TestCase]
    public void DetailsReturnsCorrectShop()
    {
      // Arrange
      int testId = 1;
      // Act
      Shop shop = this.unitOfWork.ShopRepository.Find(testId);
      ViewResult result = this.Controller.Details(testId) as ViewResult;
      // Assert
      Shop returnedShop = (Shop)result.Model;
      Assert.AreEqual(testId, returnedShop.Id);
  }

しかし、Get メソッドがリポジトリからすべてのショップを返すことをテストしたい場合、フィルター パラメーターを指定しないと、空のリストが返されます。理由がわからない?

  [TestCase]
  public void IndexReturnsListOfShops()
  {
      // Arrange
      // Act
      ViewResult result = this.Controller.Index() as ViewResult;
      // Assert
      List<Shop> returnedShops = (List<Shop>)result.Model;
      Assert.AreEqual(5, returnedShops.Count);
  }

ShopController は次のようになります。

public class ShopController : Controller
{
  private readonly IUnitOfWork unitOfWork;
  public ShopController(IUnitOfWork unitOfWork)
  {
      this.unitOfWork = unitOfWork;
  }

  // GET: /Shop/
  public ActionResult Index()
  {
      return View(this.unitOfWork.ShopRepository.Get());
  }

  // GET: /Shop/Details/5
  public ActionResult Details(int? id)
  {
      if (id == null)
      {
          return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
      }
      Shop shop = this.unitOfWork.ShopRepository.Find(id);
      if (shop == null)
      {
          return HttpNotFound();
      }
      return View(shop);
  }
}

Get メソッドから空のリストが返される理由を理解するのを手伝ってもらえますか?

4

0 に答える 0