2014-09-25 116 views
0

我喜欢模拟以下以确保ExecuteNonQuery被调用,但不知道该怎么做,因为我试过我得到了可能的异常,并且无法正确实现..我正在使用Rhino Mock如何模拟context.Database.Connection.CreateCommand

using (var command = _context.Database.Connection.CreateCommand()) 
      { 
       command.CommandText = @"testproc_ins"; 
       command.CommandType = CommandType.StoredProcedure; 
       SqlParameter[] parameters = GetParameters(transaction); 
       command.Parameters.AddRange(parameters); 
       command.Connection.Open(); 
       command.ExecuteNonQuery(); 
       command.Connection.Close(); 
      } 

回答

2

诀窍是如何安排你的代码,以便你可以用你的模拟代替真实的物体。例如:

var command = CommandFactory.CreateCommand() 

并假设CreateCommand()在真实的CommandFactory如上,_context.Database.Connection.CreateCommand()实现,但在单元测试中,你有一个返回一个模拟代替的CommandFactory。

一旦你完成了这一切,在犀牛模拟很简单:

var cmd = MockRepository.GenerateStub<IDbCommand>(); 
// Somehow pass mock cmd to code under test. For example, 
// CommandFactory here could itself be a mock, and you tell it 
// to return the mock cmd you created earlier: 
SomeObject.CommandFactory.Stub(c => c.CreateCommand()).Return(cmd); 
// Act 
// Do something 
// Assert 
cmd.AssertWasCalled(c => c.ExecuteNonQuery())); 
+0

你mean't说我需要在放置的CommandFactory和模拟的_context.Database.Connection.CreateCommand()他们。但我不喜欢为单行创建一个CommandFactory类。 – 2014-09-25 09:52:38

+0

欢迎来到使用模拟对象进行单元测试的世界:)有时候这是一种痛苦,但是没有其他简单的方法 - 您必须以某种方式注入您的依赖关系,并且您的依赖关系是创建命令的对象。另一种方法是提供你自己的_context封装,这样_context.Database.Connection就在你的直接控制之下 - 但我不知道这是否容易。 – FarmerBob 2014-09-25 09:58:16

+0

嗨,你的第二个想法为我工作。我将_context.Database.Connection作为虚拟方法包装到上下文类中,以便我可以通过嘲讽来控制它。谢了哥们。 – 2014-09-26 07:27:08