有没有办法模拟直接在方法中创建新连接的实体框架调用

本文关键字:连接 调用 框架 实体 新连接 创建 模拟 方法 有没有 | 更新日期: 2024-10-31 20:52:05

我是单元测试和模拟的新手。我正在从事的项目有许多方法,如下所示:

public bool MyMethod(int param, int param2)
{
    using (SomeEntity dBcontext = new SomeEntity())
    {
        FancyObj theobj = dBcontext.MyObjs.FirstOrDefault(l => l.ObjId == param2);
        if (theobj != null && theobj.CurrentSeason != param) //if season has changed then update
        {
            theobj .CurrentSeason = param;
            dBcontext.SaveChanges();
            return true;
        }
        return false;
    }
}

我正在使用 Telerik JustMock,除非我错过了什么,否则我无法模拟实体调用,因为它是直接在测试中的方法中实例化的。

我唯一的解决方案是修改方法/类以保存 SomeEntity 类型的属性吗?

有没有办法模拟直接在方法中创建新连接的实体框架调用

更新所需依赖项的实例(而不是在构造函数中请求它)会杀死可测试性。实质上,通过使用new运算符,您将应用程序实例化的关注点与应用程序逻辑的关注点混合在一起。

依赖注入救援!被测试的类应该要求在构造函数中完成其工作所需的所有内容,并依赖于接口,而不是具体的实现。这样,您将能够提供虚假实现,以使单元测试完全隔离。

如果不重构你的代码,我认为你可能对传统的模拟框架不走运,因为所有模拟框架都依赖于virtualinterface的方法。

但是,如果您拥有Visual Studio Premium或Ultimate版本,则可以使用Microsoft Fakes,它允许您修改/替换/拦截对非虚拟方法和属性的调用(通过在加载时修改/注入CIL代码到第三个程序集中来工作)。

虽然从长远来看,依赖注入可能是更好的方法(它通常会改善代码的结构),但有一些商业解决方案,如Typemock,允许你测试无法以传统方式测试的代码。 这有点喜忧参半,因为您可能会依赖模拟框架,并且不一定会收获使用更传统的模拟框架进行单元测试可以鼓励的结构更改。 但是,它应该允许您测试所描述的情况。

他们

网站上的一个示例显示了他们如何能够获取在其 Compute 函数中创建的对象的句柄。 如他们的其他一些示例所示,此句柄可用于设置对该依赖项的调用的期望:

public static int Calculate(int a, int b)
{
   var dependency = new Dependency();
   dependency.CheckSecurity("typemock", "rules");
   return a + b;
}
[TestMethod,Isolated]
public void FakeConstructor()
{
    // Fake the Dependency constructor
    var fakeHandle = Isolate.Fake.NextInstance<dependency>();
    var result = ClassUnderTest.Calculate(1, 2);
    Assert.AreEqual(3, result);
}

有各种不同的定价选项,我不确定每个层都能得到什么,但是如果你真的不想改变你的代码并且你有相当厚的资金,那么可能值得考虑。

是的,可以使用 JustMock 的商业版本来排列new表达式的返回值。

var mock = Mock.Create<SomeEntity>();
Mock.Arrange(() => new SomeEntity()).Returns(mock);

从这里开始,您可以安排模拟以具有测试所需的行为。如果您使用的是 EF6,则可以尝试插入 JustMock 的 Telerik.JustMock.EntityFramework,为您的测试创建内存中模拟数据库上下文。