隔离依赖关系而不发生控制反转

发布于 2024-07-27 04:25:58 字数 424 浏览 7 评论 0原文

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

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

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

谢谢

I'm working on an enterprise application that relies heavily on message queues, com+, databases, httpcontext, static utility classes etc.

Since there's 600 projects in our system it seems impractical to rewrite to use inversion of control. Typemock claims they are the only isolation framework that doesn't require you to rewrite your code to use IOC.

Does anybody know how TypeMock implemented this level of functionality and if there are any alternatives? Even if I was to rewrite my application to use inversion of control I would have to write wrapper classes for message queues, httpcontext etc. To me that just sounds ridiculous, am I right or wrong to think that Typemock is the only viable option for my scenario.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

玩套路吗 2024-08-03 04:25:58

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

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

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

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

You are right to think that TypeMock (or another similar mocking tool) is the only viable option.

It's always possible to use an AOP tool directly to provide isolation of dependencies, but the effort required to do so is significant, making it not viable in practice.

For Java, the JMockit toolkit enables isolation for all kinds of dependencies, without any necessary changes to production code.

Internally, JMockit uses the functionalities provided by the java.lang.instrument API. Basically, it allows methods/constructors to be redefined at runtime. Redefinition means the bytecode implementing the method/constructor is replaced. This can be done any number of times for the same method. Additionally, classes can be transformed at load time (i.e, any method or constructor defined in the class can have its bytecode changed just before the class is made available to the JVM).

醉南桥 2024-08-03 04:25:58

在 C# 中模拟非虚拟方法

如果不深入挖掘,答案就是 AOP技术。 由于您可以拦截方法调用或事后更改方法调用,这使得添加模拟类/实例变得非常可能。

这是 AOP 的巧妙运用。

如果您想自己执行此操作(并且我确信存在一些陷阱...),请使用开源 Aspect weaver 框架:http://csharp-source.net/open-source/aspect-oriented-frameworks

Mocking non-virtual methods in C#

Without digging really deep, the answer is AOP techniques. Since you can intercept method calls or alter method calls after-the-fact, this makes adding-in mock classes/instances very possible.

It's a clever use of AOP.

If you want to do this on your own (and I'm sure there are some pitfalls...), grab an open source Aspect weaver framework: http://csharp-source.net/open-source/aspect-oriented-frameworks

傲世九天 2024-08-03 04:25:58

如果你有一个这样的类:

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");

If you've got a class like this:

public class MotherClass
{
    private SubClass _subClass;

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

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

It's without IoC. But with Typemock Isolator you can still replace it via:

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

And even swap out the result of the SomeMethod like this:

        var fake = Isolate.Fake.Instance<SubClass>();
        Isolate.WhenCalled(() => fake.SomeMethod()).WillReturn("Bye");
独孤求败 2024-08-03 04:25:58

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

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

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

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

Most mocking frameworks do rely on some form of IOC. This is because IOC is in fact a good practice. Aside from testing, imagine you have a class that looks up a database connection (rather than injecting it), and now the class of database connection changes. You shouldn't have to recompile your code - you should just be able to change the injected dependency. From a testing perspective, you could do the same thing, inject a mock database service.

To get more toward your question. I would focus on gradually refactoring to an injection instead of a hard coded lookup framework. Start with the big pieces, like databases and other 3rd party services. As you refactor them out, you can use any mock framework (I've used EasyMock and I like it, but there are others - JMock, Mockito). These frameworks do not require wrapper classes, but generally rely on proxy objects. When you create a mock, you are actually creating a proxy (which is an instanceof the class type you are mocking).

Bytecode manipulation (Aspect Oriented for example, as Typemock uses) can be dangerous to rely heavy on. Often times you might have other tools that also manipulate byte code (code coverage tools frequently do this) and multiple bytecode manipulations can cause unexpected behavior.

Lastly, you can look at languages like Groovy. Groovy works well with Java (it gets compile to bytecode) and has mocking built right into the language. Some Google searches for mock objects with Groovy should return some good results.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文