【发布时间】:2023-03-10 00:01:01
【问题描述】:
我目前正在与 CDI Unit 合作开展一个项目,但遇到了一个奇怪的问题。我试图在一个简单的项目中重现它:
我有一个使用 CdiRunner 运行的测试类(如下所述:http://jglue.org/cdi-unit-user-guide/ 我的测试类注入被测单元:UUD。该类扩展了一个当前无用的超类“ParentTestClass”。
TestClass.java:
package fr.perso.tutorial.cdiunit.test;
import javax.inject.Inject;
import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
import fr.perso.tutorial.cdiunit.controller.UUD;
@RunWith(CdiRunner.class)
public class TestClass extends ParentTestClass {
@Inject
private UUD uud;
@Produces
@Mock
private MyController myController;
@Test
public void test() {
}
}
正如我提到的,父类是空的。
ParentTestClass.java:
package fr.perso.tutorial.cdiunit.test;
public class ParentTestClass {
}
正如我们所见,被测单元需要 MyController 才能工作。这就是我在 TestClass 中制作 Mock 的原因。
UUD.java:
package fr.perso.tutorial.cdiunit.controller;
import javax.inject.Inject;
import org.junit.Before;
public class UUD {
@Inject
private MyController myController;
@Before
private void initialize(){
System.out.println("I'm the unit under test and i need this controller to work : " + myController.toString());
}
}
MyController .java :
package fr.perso.tutorial.cdiunit.controller;
public class MyController {
@Override
public String toString() {
return "[controller : " + super.toString() + "]";
}
}
好的,问题来了:当我们在TestClass中声明mock时,测试就ok了。但是如果我在 ParentTestClass 中声明它,就会出现以下错误:
org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type MyController with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private fr.perso.tutorial.cdiunit.controller.UUD.myController
at fr.perso.tutorial.cdiunit.controller.UUD.myController(UUD.java:0)
Possible dependencies:
- Producer Field [MyController] with qualifiers [@Any @Default] declared as [[UnbackedAnnotatedField] @Produces @Mock private fr.perso.tutorial.cdiunit.test.TestClass.myController],
- Managed Bean [class fr.perso.tutorial.cdiunit.controller.MyController] with qualifiers [@Any @Default],
- Producer Field [MyController] with qualifiers [@Any @Default] declared as [[BackedAnnotatedField] @Produces @Mock private fr.perso.tutorial.cdiunit.test.ParentTestClass.myController]
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:367)
at org.jboss.weld.bootstrap.Validator.validateInjectionPoint(Validator.java:281)
at org.jboss.weld.bootstrap.Validator.validateGeneralBean(Validator.java:134)
at org.jboss.weld.bootstrap.Validator.validateRIBean(Validator.java:155)
at org.jboss.weld.bootstrap.Validator.validateBean(Validator.java:518)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:68)
at org.jboss.weld.bootstrap.ConcurrentValidator$1.doWork(ConcurrentValidator.java:66)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:60)
at org.jboss.weld.executor.IterativeWorkerTaskFactory$1.call(IterativeWorkerTaskFactory.java:53)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
我本来希望在超类中创建模拟,以便在我的项目中重复代码。我知道有些人认为使用超级测试类是一种代码味道(例如:https://www.petrikainulainen.net/programming/unit-testing/3-reasons-why-we-should-not-use-inheritance-in-our-tests/)
即使我不完全同意这篇文章(我可能错了,好吧),它也没有解释为什么我们在超类中创建模拟时会出现模棱两可的依赖问题。
有谁知道为什么会出现这个问题并知道如何解决它,除非将所有代码都写在一个类中?
非常感谢您的帮助!
【问题讨论】:
标签: java unit-testing dependency-injection cdi