假设我有一个像这样的程序:
@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);
}
}
如果我通过Eclipse运行它,它可以正常工作(主方法在创建Spring的mainAction
之后实际上调用mainAction.doTheAction()
)。
现在我想编写一个测试,确保在调用doTheAction
时正确调用了log
方法。 我们正在使用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();
}
}
@ContextConfiguration
可能是无用的。以前我试过@RunWith(SpringJunit4ClassRunner.class)
,所以@ContextConfiguration
在这里,但是没有处理任何模拟相关的东西。此外,我使用@Tested
和@Injectable
代替@Autowired
和@Mocked
,遵循这个问题中的建议;如果不这样做,mainAction
仍然为 null。所以现在测试运行了,并且“Now doing the action”出现在输出中。但是,“The @Before advice has run”没有出现(即使不模拟Logger
也没有出现),期望失败。如何同时使用JMockit和AOP? 编辑:按要求,我添加了一些内容来打印类路径属性。这里是它的内容(其中省略了一些路径名的不重要部分):
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/
编辑2: 我通过在“配置构建路径”中的“库”选项卡中删除JUnit4,使事情得以解决。
@Capturing
而不是@Injectable
。 - RogérioMethod testThatLoggerIsCalled should have no parameters
(来自SpringJUnit4ClassRunner.java内部),如果我使用@RunWith(JMockit.class)
,我就不会得到这个错误。 我正在使用Maven依赖项,并将jmockit
移动到了pom.xml中的junit
之上(实际上,jmockit
现在是第一个),并清理和重建了项目。 那么我还忘记做什么? - ajbSpringJUnit4ClassRunner
,所以我放弃了这个想法。)但是似乎可能有一些JMockit功能可以在没有@RunWith(JMockit.class)
的情况下工作,而有些则不行。是否有一个不起作用的功能列表? - ajb@RunWith(JMockit.class)
的情况下工作;如果使用其他自定义测试运行器(例如SpringJUnit4ClassRunner
),则可能会或可能不会工作,这取决于该自定义运行器的实现方式。 - Rogério