我正在使用为数据库调用方法附带IDatabase类的NPoco。我想验证进入NPoco Insert方法的对象是否具有正确的数据(以域对象的形式)。如何在moq中调试验证?
public interface IUnitOfWorkProvider
{
IUnitOfWork GetUnitOfWork();
}
public interface IUnitOfWork : IDisposable
{
void Commit();
IDatabase Db { get; }
void SetOneTimeCommandTimeout(int timeout);
void SetGlobalCommandTimeout(int timeout);
}
public interface IDatabase : IDatabaseQuery
{
IDbConnection Connection { get; }
IDbTransaction Transaction { get; }
void AbortTransaction();
void BeginTransaction();
void BeginTransaction(IsolationLevel? isolationLevel);
void CompleteTransaction();
IDataParameter CreateParameter();
int Delete(object poco);
int Delete<T>(object pocoOrPrimaryKey);
int Delete<T>(Sql sql);
int Delete<T>(string sql, params object[] args);
int Delete(string tableName, string primaryKeyName, object poco);
int Delete(string tableName, string primaryKeyName, object poco, object primaryKeyValue);
void Dispose();
Transaction GetTransaction();
Transaction GetTransaction(IsolationLevel? isolationLevel);
object Insert(object poco);
object Insert(string tableName, string primaryKeyName, object poco);
object Insert(string tableName, string primaryKeyName, bool autoIncrement, object poco);
void Save(object poco);
void Save(string tableName, string primaryKeyName, object poco);
IDatabase SetTransaction(IDbTransaction tran);
int Update(object poco);
int Update<T>(Sql sql);
int Update(object poco, IEnumerable<string> columns);
int Update(object poco, object primaryKeyValue);
int Update<T>(string sql, params object[] args);
int Update(object poco, object primaryKeyValue, IEnumerable<string> columns);
int Update(string tableName, string primaryKeyName, object poco);
int Update(string tableName, string primaryKeyName, object poco, IEnumerable<string> columns);
int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue);
int Update(string tableName, string primaryKeyName, object poco, object primaryKeyValue, IEnumerable<string> columns);
}
// my test class file
private IFixture fixture;
private Mock<IUnitOfWork> unitOfWork;
private MyService myService;
private Mock<IDatabase> database; // new based on responses
[SetUp]
public void Setup()
{
fixture = new Fixture().Customize(new AutoMoqCustomization());
database = fixture.Freeze<Mock<IDatabase>>();// new based on responses
unitOfWork = fixture.Freeze<Mock<IUnitOfWork>>();
myService = fixture.CreateAnonymous<MyService>();
}
[Test]
public MyTest()
{
// fails
unitOfWork.Setup(x => x.Db.Insert(It.IsAny<MyDomainObject>()));
myService.CallMyMethod();
unitOfWork.Verify(x => x.Db.Insert(It.IsAny<MyDomainObject>()));
// fails
unitOfWork.Setup(x => x.Db.Insert(It.IsAny<object>()));
myService.CallMyMethod();
unitOfWork.Verify(x => x.Db.Insert(It.IsAny<object>()));
// fails (this was a try based on responses)
database.Setup(x => x.Insert(It.IsAny<object>()));
myService.CallMyMethod();
database.Verify(x => x.Insert(It.IsAny<object>()));
// passes
unitOfWork.Setup(x => x.Db.Insert(It.IsAny<object>()));
myService.CallMyMethod();
unitOfWork.Verify();
}
public class MyDomainObject
{
public void Id {get; set;}
}
的代码被称为(我应该触发验证)
using (var unitOfWork = unitOfWorkProvider.GetUnitOfWork())
{
MyDomainObject myDomain = anotherService.getMyDomain(DateTime.Now, 100);
unitOfWork.Db.Insert(myDomain);
}
你的设置不从我所能看到的嘲笑 - 也就是说你可以做'x.Db',但是当你点到另一个关卡时,你不在Setup表达式可以做的事情上 - 这一点被'Verify( )'的作品[因为你是呼号'x.Db']。但也许你已经剥去了太多。 –
我会更新我的帖子。 – chobo2
就像Ruben怀疑的那样,'IDatabase Db'得到*自动模拟*,并且您对错误的对象设置了期望值。通常,在执行'x => x.Db ...'位('Db'为空)时,您会得到空引用异常,但是由于您使用了AutoFixture,因此它会静默地通过。你最后一个例子的作用只是因为对'unitOfWork'完全没有期望。我建议你'冻结''IDatabase'并设置它的期望值。 –