2016-09-12 221 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和現場製片人的工作。