我可以使用MOQ </t>模拟实体框架的Objectresult <t>

时间:2010-05-25 18:47:43

标签: entity-framework-4 moq

我正在使用Entity Frameowrk 4.0并且我正在调用一个返回ObjectResult的存储过程,并且我尝试使用MOQ并且无法模拟ObjectResult。有没有人能够使用moq模拟ObjectResult?

TIA 雅致

3 个答案:

答案 0 :(得分:4)

我也有这个问题;我正在使用数据库优先设计和EF 4.x DbContext Generator模板来生成我的DbContext。

我正在通过以下方式修改上下文生成器:

  1. 代替DbSet&lt; T&gt;对于实体集,我将返回IDbSet&lt; T&gt ;;这允许我使用InMemoryDbSet&lt; T&gt;用于单元测试(Google用于实现);
  2. 而不是ObjectResult&lt; T&gt;对于存储过程,我返回IEnumerable&lt; T&gt;。在为存储过程创建的虚方法中,我加载了ObjectResult&lt; T&gt;到列表&lt; T&gt;并返回;
  3. 最后,我提取了一个暴露实体集和函数导入的接口。这意味着我可以模拟整个DbContext进行超高速单元测试。当然,您仍应编写用于测试数据库功能的集成测试。

答案 1 :(得分:2)

ObjectResult(according to the MSDN docs)是一个密封的类,你不能嘲笑它。像Moq这样的Mocking库的工作方式是当你做像

这样的事情时
Mock<Foo> fooMock = new Mock<Foo>();

它生成(使用Reflection.Emit和其他各种魔术技巧)一个看起来有点像这样的类

public class FooMockingProxy : Foo {

    public override void This() {
        // Mocking interceptors to support Verify and Setup
    }

    public override string That() {
        // Mocking interceptors to support Verify and Setup
    }

}

即。它需要你想要的类(接口)Mock和它的子类(或者在接口的情况下实现它)。这允许它放入检测,允许它检查方法是否已被调用,或返回某个值(这支持各种Setup和Verify方法)。这种模拟方法的限制是: -

  • 密封类(不能分类)
  • 私有成员(无法从子类访问)
  • 非虚拟的方法或属性类(因此无法覆盖)。

接近密封类时可以采用的一种技术是将它们包装在某种Mockable接口中。或者,您可以尝试并模拟密封类实现的接口,只有您的代码消耗。

答案 2 :(得分:0)

我找不到模拟密封类的方法,并想测试存储过程的参数是否与实体模型匹配。这是我的解决方案:

 namespace CardiacMonitoringTest
{
    [TestClass]
    public class CardiacMonitoringDataTest
    {
        [TestMethod]
        public void TestEntityStoredProcedure()
        {
            List<string> SPExceptions = new List<string>();
            SPExceptions.Add("AfibBurdenByDay");
            SPExceptions.Add("GetEventTotalsByCategory");

            EntitiesCon db = new EntitiesCon();
            foreach (MethodInfo mi in typeof(EntitiesCon).GetMethods())
            {

                string ptype = mi.ReturnType.Name;
                if (ptype.IndexOf("ObjectResult") > -1)
                {
                    List<SqlParameter> ExtractedParameters = SPListParm(ConfigurationManager.ConnectionStrings["CardiacMonitoring"].ConnectionString, mi.Name);
                ExtractedParameters = ExtractedParameters.Where(a => a.ParameterName != "@RETURN_VALUE" && a.ParameterName != "@TABLE_RETURN_VALUE").ToList();
                ParameterInfo[] EntityParameters = mi.GetParameters();
                if ((from b in SPExceptions where b.ToLower() == mi.Name.ToLower() select b).Count() > 0)
                {
                    continue;
                }
                foreach (ParameterInfo pi in EntityParameters)
                {


                        try
                        {
                            Assert.IsTrue(
                                (from a in ExtractedParameters where pi.Name.ToLower() == a.ParameterName.Replace("@", "").ToLower() select a).Count() == 1);
                        }
                        catch (Exception ex)
                        {
                            Trace.WriteLine("Failed SP:" + mi.Name + " at parameter:" + pi.Name);
                            throw (ex);
                        }
                    try
                    {
                        Assert.IsTrue(EntityParameters.Count() == ExtractedParameters.Count());
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine("Failed SP:" + mi.Name + " on parameter count:" + EntityParameters.Count() + " with detected count as:" + ExtractedParameters.Count());
                        throw (ex);
                    }
                }
            }
            }
        }

        private List<SqlParameter> SPListParm(string ConnectionString, string SPName)
        {
            try
            {
                SqlConnection conn = new SqlConnection(ConnectionString);
                SqlCommand cmd = new SqlCommand(SPName, conn);
                cmd.CommandType = CommandType.StoredProcedure;
                conn.Open();
                SqlCommandBuilder.DeriveParameters(cmd);
                SqlParameter[] prmDetectParameters = new SqlParameter[cmd.Parameters.Count];
                cmd.Parameters.CopyTo(prmDetectParameters, 0);
                List<SqlParameter> toReturn = new List<SqlParameter>();
                toReturn.AddRange(prmDetectParameters);
                return (toReturn);
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Failed detecting parameters for SP:" + SPName);
                throw (ex);
            }
        }
    }
}