3

我正在开发一个严重依赖消息队列、com+、数据库、httpcontext、静态实用程序类等的企业应用程序。

由于我们的系统中有 600 个项目,因此重写以使用控制反转似乎是不切实际的。Typemock 声称它们是唯一不需要您重写代码即可使用 IOC的隔离框架。

有谁知道 TypeMock 是如何实现这种级别的功能的,以及是否有任何替代方案?即使我要重写我的应用程序以使用控制反转,我也必须为消息队列、httpcontext 等编写包装类。对我来说这听起来很荒谬,我认为 Typemock 是我唯一可行的选择是对还是错设想。

谢谢

4

4 回答 4

1

在 C# 中模拟非虚方法

无需深入挖掘,答案就是 AOP 技术。由于您可以在事后拦截方法调用或更改方法调用,这使得添加模拟类/实例成为可能。

这是对 AOP 的巧妙使用。

如果你想自己做这件事(我敢肯定有一些陷阱......),抓住一个开源的 Aspect weaver 框架: http ://csharp-source.net/open-source/aspect-oriented-构架

于 2009-07-14T21:45:56.340 回答
1

您认为 TypeMock(或其他类似的模拟工具)是唯一可行的选择是正确的。

总是可以直接使用 AOP 工具来提供依赖关系的隔离,但这样做所需的工作量很大,因此在实践中不可行。

对于 Java,JMockit工具包可以隔离所有类型的依赖项,而无需对生产代码进行任何必要的更改。

在内部,JMockit 使用java.lang.instrumentAPI 提供的功能。基本上,它允许在运行时重新定义方法/构造函数。重新定义意味着实现方法/构造函数的字节码被替换。对于相同的方法,可以多次执行此操作。此外,类可以在加载时进行转换(即,类中定义的任何方法或构造函数都可以在类可用于 JVM 之前更改其字节码)。

于 2009-07-25T16:10:01.813 回答
1

如果你有这样的课程:

public class MotherClass
{
    private SubClass _subClass;

    public MotherClass()
    {
        _subClass = new SubClass();
    }
}

public class SubClass
{
    public string SomeMethod()
    {
        return "Hello";
    }
}

它没有 IoC。但是使用 Typemock Isolator,您仍然可以通过以下方式替换它:

    [TestMethod]
    public void TestMethod()
    {
        var fake = Isolate.Fake.Instance<SubClass>();
        Isolate.Swap.NextInstance<SubClass>().With(fake);
    }

甚至像这样交换 SomeMethod 的结果:

        var fake = Isolate.Fake.Instance<SubClass>();
        Isolate.WhenCalled(() => fake.SomeMethod()).WillReturn("Bye");
于 2009-07-30T10:32:01.430 回答
0

大多数模拟框架确实依赖于某种形式的 IOC。这是因为 IOC 实际上是一种很好的做法。除了测试之外,假设您有一个查找数据库连接(而不是注入它)的类,现在数据库连接的类发生了变化。您不必重新编译代码 - 您应该能够更改注入的依赖项。从测试的角度来看,你可以做同样的事情,注入一个模拟数据库服务。

为了更多地了解您的问题。我将专注于逐步重构为注入而不是硬编码的查找框架。从大件开始,例如数据库和其他 3rd 方服务。当您重构它们时,您可以使用任何模拟框架(我使用过 EasyMock 并且我喜欢它,但还有其他的 - JMock、Mockito)。这些框架不需要包装类,但通常依赖于代理对象。当你创建一个模拟时,你实际上是在创建一个代理(它是你模拟的类类型的一个实例)。

字节码操作(例如,面向方面,如 Typemock 所使用的)可能很危险,严重依赖。通常,您可能还有其他工具也可以操作字节码(代码覆盖工具经常这样做),并且多个字节码操作可能会导致意外行为。

最后,您可以查看 Groovy 之类的语言。Groovy 与 Java 配合得很好(它可以编译为字节码),并且在语言中内置了 mock。一些使用 Groovy 搜索模拟对象的 Google 搜索应该会返回一些不错的结果。

于 2009-07-15T03:46:48.940 回答