MVC コントローラーをテストできるように、コードをモックするのに実際に問題があります。
私のリポジトリは次のインターフェースを実装しています
public interface IEntityRepository<T>
{
IQueryable<T> All { get; }
IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties);
void Delete(int id);
T Find(int id);
void InsertOrUpdate(T entity);
void InsertOrUpdateGraph(T entity);
}
そのようです
public interface IMonkeyRepository : IEntityRepository<Monkey>
{
}
私のEFコンテキストは、次のインターフェースを実装しています
public interface IMonkeyContext
{
IDbSet<Monkey> Monkeys { get; set; }
DbEntityEntry Entry(object entity);
IEnumerable<DbEntityValidationResult> GetValidationErrors();
int SaveChanges();
}
私の作業単位インターフェースはそのように定義されています
public interface IUnitOfWork<TContext> : IDisposable
{
TContext Context { get; }
int Save();
}
そして実装
public class MonkeyUnitOfWork : IUnitOfWork<IMonkeyContext>
{
private readonly IMonkeyContext context;
private bool disposed;
public MonkeyUnitOfWork(IMonkeyContext context)
{
this.context = context;
}
public IMonkeyContext Context
{
get
{
return this.context;
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
public int Save()
{
var ret = this.context.SaveChanges();
return ret;
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
((DbContext)this.context).Dispose();
}
}
this.disposed = true;
}
}
テストしたい Create アクションの MonkeyController があります。私は定義されています
if (this.ModelState.IsValid)
{
this.repo.InsertOrUpdate(Mapper.Map<MonkeyModel, Monkey>(monkey));
this.uow.Save();
return this.RedirectToAction(MVC.Monkey.Index());
}
return this.View(monkey);
私の単体テストでは、RhinoMocks を使用しており、テストを定義しています。
[TestFixture]
public class MonkeyControllerTests
{
MockRepository mocks = null;
private IMonkeyRepository monkeyRepository;
private IMonkeyContext context;
private MonkeyUnitOfWork unitOfWork;
private MonkeyController controller;
[SetUp]
public virtual void SetUp()
{
TestHelpers.SetupAutoMap();
this.monkeyRepository = this.Mocks.StrictMultiMock<IMonkeyRepository>(typeof(IEntityRepository<Monkey>));
this.context = this.Mocks.StrictMock<IMonkeyContext>();
this.unitOfWork = new MonkeyUnitOfWork(this.context);
this.controller = new MonkeyController(this.MonkeyRepository, this.unitOfWork);
}
[TearDown]
public virtual void TearDown()
{
if (this.mocks != null)
{
try
{
this.mocks.ReplayAll();
this.mocks.VerifyAll();
}
finally
{
this.mocks = null;
}
}
}
public MockRepository Mocks
{
get
{
if (mocks == null)
mocks = new MockRepository();
return mocks;
}
}
[Test]
public void MonkeyCreateShouldShouldDoSomeStuff()
{
var monkeyModel = ViewModelTestHelpers.CreateSingleMonkey();
var monkey = Mapper.Map<MonkeyModel, Monkey>(monkeyModel);
this.monkeyRepository.Expect(action => action.InsertOrUpdate(monkey));
this.context.Expect(action => action.SaveChanges()).Return(1);
var result = (RedirectToRouteResult)this.controller.Create(monkeyModel);
Assert.AreEqual(MVC.Monnkey.ActionNames.Index, result.RouteValues["action"]);
}
}
テストを実行すると、次のエラーが発生します
前のメソッド「IMonkeyContext.SaveChanges();」戻り値またはスローする例外が必要です。
または、IEntityRepository.InsertOrUpdate が 1 実際の 0 を期待していると不平を言います
これを機能させるために非常に多くのキャストと呪文を試しましたが、困惑しています。これらのオブジェクトを正しくモックする方法を知っている人はいますか? または、ここで根本的に何かを見逃した場合は?