简体   繁体   English

在 Junit 或 Groovy/Spock 测试中测试匿名 class

[英]Test anonymous class in Junit or Groovy/Spock test

I am trying to write units tests in Groovy/Spock and have to test the below code.我正在尝试在 Groovy/Spock 中编写单元测试,并且必须测试以下代码。

public class ClassA {
    @Inject
    private ClassB classB;

    @Inject
    private ClassC classC;

    @Inject
    private ClassD classD;

    public void update(final int a, final Map<String, Object> b) {
        classB.executeCommand(classC.callToMethodInClassC(), new InterfaceE<Void>() {
            @Override
            public Void execute() {
                classD.update(a, b);
                return null;
            }
        });
    }
}

Now when I write test code I am unable to reach classD.update(a, b);现在,当我编写测试代码时,我无法访问classD.update(a, b); line.线。 I know how to inject mocks/real object for ClassB, ClassC, ClassD, but unable to reach that statement.我知道如何为 ClassB、ClassC、ClassD 注入模拟/真实 object,但无法达到该声明。 Please help.请帮忙。

Note: ClassA.update() & ClassD.update() have no relation between them except that their signatures match.注意: ClassA.update()ClassD.update()之间没有任何关系,只是它们的签名匹配。

Make your classB mock like this:让你的 classB 像这样模拟:

Mock(ClassB) {
    executeCommand(_, _) >> { c, e -> e.execute() }
}

Ie provide a mock implementation for the executeCommand method of ClassB that actually calls the execute method of interfaceE.即为ClassB的executeCommand方法提供一个mock实现,实际上调用interfaceE的execute方法。

EDIT: full working example:编辑:完整的工作示例:

import spock.lang.Specification

class TestMeSpec extends Specification {

    def "my test"() {
        def b = Mock( ClassB ) {
            executeCommand( _, _ ) >> { c, e -> e.execute() }
        }
        def c = Mock( ClassC )
        def d = Mock( ClassD )

        def a = new ClassA( classB: b, classC: c, classD: d )

        when:
        a.update( 0, [ : ] )

        then:
        1 * d.update( 0, [ : ] )
    }
}

class ClassA {
    ClassB classB
    ClassC classC
    ClassD classD

    void update( final int a, final Map<String, Object> b ) {
        classB.executeCommand( classC.callToMethodInClassC(), new InterfaceE<Void>() {
            @Override
            Void execute() {
                classD.update( a, b )
            }
        } )
    }
}

class ClassB {
    void executeCommand( c, InterfaceE e ) {
        println "REAL CLASS B executCommand() METHOD RUNNING"
    }
}

class ClassC {
    def callToMethodInClassC() {}
}

class ClassD {
    void update( a, b ) {
        println "REAL CLASS D update() method called with $a and $b"
    }
}

interface InterfaceE<T> {
    T execute()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM