【问题标题】:Instance metaclass changes leaking from instance to instance?实例元类更改从实例泄漏到实例?
【发布时间】:2012-08-24 01:58:08
【问题描述】:

我有两个 junit 单元测试,一个测试函数是否成功,另一个测试异常发生时的故障恢复代码。

CUT(被测类)实例在 setUp 方法中实例化。

在失败测试用例的序言中,我通过覆盖实例元类中的方法来覆盖 cut 的方法之一以引发异常:

cut.metaClass.internalWork ={throw new RuntimeException('Failing')}

据我了解对象的元编程(不是它的静态类),当您实例化一个新对象时,这个新对象的元类不受您在旧实例上执行的任何元编程的影响,但这就是我所观察到的,因为我看到在执行我的成功场景时,实际抛出了在用于失败测试用例的剪切实例中设置的运行时异常。

如果您需要更多详细信息,请告诉我,我只是想确保我没有犯基本的理论错误。

谢谢。

更新

这是为了说明我的测试用例应该如何工作:

class Cut {
    int fn() {
        internalWork()
        1
    }

    void internalWork() {
        println "Doin work"
    }
}

class WtfTests extends TestSupport {
    @Override
    protected void setUp() {
        println "creating new MS instance"
        cut = new Cut()
    }

    void testSuccess() {
        println "testSuccess"
        cut.fn()
    }

    void testFailure() {
        println "testFailure"
        cut.metaClass.internalWork={->
            println "Won't do work"
            throw new RuntimeException('Failing')
        }
        assert 'Failing'==shouldFail(RuntimeException) {
            cut.fn()
        }
    }
}

这几乎可以按预期工作:

创建新的 MS 实例
测试失败
不会工作
创建新的 MS 实例
测试成功
干活

更新 2

顺便加个

registerMetaClass(MyClass)

到 setUp 方法,我解决了这个问题,但这应该只保存静态元类,而不是实例的元类,所以现在我完全糊涂了,因为如上面的示例所示,这应该无关紧要。 .. ?

【问题讨论】:

  • 你的理解是正确的。对实例元类的更改不应影响同一类的其他实例。我无法使用您发布的代码重现该问题。一定有其他事情发生。你能发布一个显示行为的测试用例吗?
  • 嗨,我发布的测试用例确实没有表现出我真实世界测试用例的行为。我主要是在寻找澄清或确认我的理解是正确的。它可能与我目前无法确定的静态类元编程和实例元编程之间的某些交互有关。

标签: grails groovy


【解决方案1】:

你必须清理 CUT 元类

测试

@After
public void tearDown() {
    def remove = GroovySystem.metaClassRegistry.&removeMetaClass
    println "Cleaning CUT"
    remove CUT
    remove CUT1
    remove CUT2
}

【讨论】:

  • 要明确一点,如果我有 A 类,以及 A 类的实例切割。如果我操作切割 INSTANCE 的元类,我也应该清理 A 的元类(实例的类)?
  • 当你模拟一个使用Class metaClass的类实例时,你不应该使用实例metaClass。小论文可以看:jira.grails.org/browse/…
  • 我完全不确定 jira 如何应用于我的示例。我不使用mockFor,我使用groovy 1.6+
  • 是的,兄弟,但问题是一样的。您正在模拟一个类,并且您正在“元分类”该类中的一个实例。因此,您将类 metaClass 和实例 metaClass 组合在一起,这可能会搞砸所有事情。
  • 对不起,你是对的,而且非常有趣的是 registerMetaClass 的东西。我在问我,您的测试运行的上下文是什么?是单元测试还是集成测试? CUT 是域类吗?我无法复制错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 2022-10-15
  • 1970-01-01
相关资源
最近更新 更多