2016-09-12 170 views
2

我目前正在使用CDI单元进行一个项目,并且遇到了一个奇怪的问题。我试图重现它在一个简单的项目:单元测试:在父测试类中生成被测单元的模拟

我有,我有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() { 

    } 
} 

正如我mentionned,父类是空

ParentTestClass.java:

package fr.perso.tutorial.cdiunit.test; 


public class ParentTestClass { 

} 

我们可以看到,被测单元需要向myController的工作。这就是为什么我在我的TestClass中制作了一个模拟器。

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()); 
    } 
} 

的.java myController的:

package fr.perso.tutorial.cdiunit.controller; 

public class MyController { 

    @Override 
    public String toString() { 
     return "[controller : " + super.toString() + "]"; 
    } 
} 

好现在的问题是:当我们在TestClass中声明模拟,测试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/

即使我不完全同意这篇文章(并且我可能错了),它并不能解释为什么当我们在超类中创建模拟时存在一个模糊的依赖关系问题。

任何人都知道为什么有这个问题,并知道如何解决它,除非写在一个类的所有代码?

非常感谢您的帮助!

回答

0

我偶然发现了同样的事情。 答案在这里:https://stackoverflow.com/a/32985745/6324171

当你试图在抽象类或父类中产生因为@Produces不会被继承时,它不起作用。

我将我的模拟生产者切换到另一个类(如在其他答案中所建议的那样),它按预期工作。

我不得不上形成消气使用@Produces虽然:

public class DateAndTimeMasterForTestProducer { 

    @Produces 
    @ApplicationScoped 
    public DateAndTimeMaster getDateAndTimeMaster() { 
     return mock(DateAndTimeMasterImpl.class); 
    } 

} 

我很遗憾没能与来自对的Mockito注释@Mock和现场制片人的工作。