一起使用JMockit和Spring AOP

ajb*_*ajb 7 java junit jmockit spring-aop

假设我有一个如下所示的程序:

@Component
public class MainAction {
    public void doTheAction() {
        System.out.println("Now doing the action");
    }
}

@Aspect
@Component
public class BeforeAspect {
    @Autowired
    private Logger logger;

    @Before("execution(* thepackagename.MainAction.*(..))")
    public void doBefore() {
        logger.log("The @Before advice has run");
    }
}

@Component
public class Logger {
    public void log(String s) {
        System.out.println(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我通过的Eclipse(main方法调用esentially运行它,这是工作的罚款mainAction.doTheAction()后,mainAction被Spring创建).

现在我想编写一个测试,确保在log调用时正确doTheAction调用该方法.我们正在使用JMockit进行测试.(这是我实际遇到的问题的一个非常简化的情况;通过AOP方面调用更复杂的记录器,并且正在记录错误的某些值.在进行修复之前,我正在尝试编写一个测试以确保记录的值是正确的.)

这就是我的(简化)测试目前的样子:

@RunWith(JMockit.class)
@ContextConfiguration(locations = {"classpath:Beans.xml"})
public class MainActionTest {
    @Tested
    private MainAction mainAction;

    @Test
    public void testThatLoggerIsCalled(@Injectable Logger logger) {
        new Expectations() { {
            logger.log(anyString);
        } };
        mainAction.doTheAction();
    }
}
Run Code Online (Sandbox Code Playgroud)

@ContextConfiguration可能是无用的.早些时候我曾尝试过@RunWith(SpringJunit4ClassRunner.class),这就是为什么@ContextConfiguration会这样,但没有一个嘲弄的东西被处理掉了.另外,我正在使用@Tested@Injectable不是@Autowired并且@Mocked遵循这个问题的建议; 没有它,mainAction仍然是空的.所以现在测试运行,并Now doing the action出现在输出中.但是The @Before advice has run没有出现(即使我不嘲笑也不会出现Logger),并且期望失败.

我如何一起使用JMockit和AOP?

编辑:根据要求,我添加了一些东西来打印classpath属性.这是(删除了一些路径名的不重要部分):

Eclipse workspaces\springtest8\target\test-classes
Eclipse workspaces\springtest8\target\classes
C:\eclipse\plugins\org.junit_4.11.0.v201303080030\junit.jar
C:\eclipse\plugins\org.hamcrest.core_1.3.0.v201303031735.jar
.m2\repository\org\jmockit\jmockit\1.18\jmockit-1.18.jar
.m2\repository\junit\junit\4.11\junit-4.11.jar
.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar
.m2\repository\org\springframework\spring-context\4.2.0.RELEASE\spring-context-4.2.0.RELEASE.jar
.m2\repository\org\springframework\spring-aop\4.2.0.RELEASE\spring-aop-4.2.0.RELEASE.jar
.m2\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar
.m2\repository\org\springframework\spring-beans\4.2.0.RELEASE\spring-beans-4.2.0.RELEASE.jar
.m2\repository\org\springframework\spring-core\4.2.0.RELEASE\spring-core-4.2.0.RELEASE.jar
.m2\repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar
.m2\repository\org\springframework\spring-expression\4.2.0.RELEASE\spring-expression-4.2.0.RELEASE.jar
.m2\repository\org\aspectj\aspectjrt\1.8.6\aspectjrt-1.8.6.jar
.m2\repository\org\aspectj\aspectjweaver\1.8.6\aspectjweaver-1.8.6.jar
.m2\repository\org\springframework\spring-test\4.2.0.RELEASE\spring-test-4.2.0.RELEASE.jar
.m2\repository\javax\inject\javax.inject\1\javax.inject-1.jar
/C:/eclipse/configuration/org.eclipse.osgi/bundles/201/1/.cp/
/C:/eclipse/configuration/org.eclipse.osgi/bundles/200/1/.cp/
Run Code Online (Sandbox Code Playgroud)

编辑2:我通过从配置构建路径中的库选项卡中删除JUnit4来完成工作.

Rog*_*rio 3

使用 Spring 3.0 或更高版本(使用 Spring 3.0.7、4.0.5 和 4.2.0 进行测试),以下测试工作正常:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:beans.xml")
public class MainActionTest
{
    @Inject MainAction mainAction;

    @Test
    public void testThatLoggerIsCalled(@Mocked final Logger logger)
    {
        mainAction.doTheAction();

        new Verifications() {{ logger.log(anyString); }};
    }
}
Run Code Online (Sandbox Code Playgroud)