@Qualifier在Junit4

时间:2016-04-22 08:09:04

标签: java spring junit

我尝试通过阅读Spring in action 4来提高我的Spring知识。 当我要分段,描述使用限定符注释(3.3.2)时,我遇到了问题。 为了测试这个注释的作用,我编写了Dessert接口,它由3个类实现,使用@Component注释在上下文中创建。 我还创建了类Taster,它“尝试”一些甜点,由一些限定符自动装配。 当我运行我的应用程序时,使用AnnotationConfigApplicationContext - 一切正常。使用SpringJUnit4ClassRunner - 它没有。我想我在测试代码中遗漏了一些东西,但是我没有足够的知识去实现什么。 接口:

package bakery.intrface;
@FunctionalInterface
public interface Dessert {
    void introduce();
}

蛋糕:

package bakery.desserts;

import bakery.intrface.Dessert;
import org.springframework.stereotype.Component;

@Component
public class Cake implements Dessert {
    @Override
    public void introduce() {
        System.out.println("I am a cake!");
    }
}

的Cookie:

package bakery.desserts;

import bakery.intrface.Dessert;
import org.springframework.stereotype.Component;

@Component
public class Cookie implements Dessert {
    @Override
    public void introduce() {
        System.out.println("I'm a cookie!");
    }
}

冰淇淋:

package bakery.desserts;

import bakery.intrface.Dessert;
import org.springframework.stereotype.Component;

@Component
public class IceCream implements Dessert {
    @Override
    public void introduce() {
        System.out.println("I'm an ice cream!");
    }
}

这个类,消耗一些bean,Taster:

package bakery;

import bakery.intrface.Dessert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class Taster {

    private Dessert dessert;

    public void taste(){
        dessert.introduce();
    }

    @Autowired
    @Qualifier("iceCream")
    public void setDessert(Dessert dessert) {
        this.dessert = dessert;
    }
}

配置:

package bakery.config;

import bakery.Bakery;
import bakery.Taster;
import bakery.desserts.Cake;
import bakery.intrface.Dessert;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackageClasses = Bakery.class)
public class BakeryConfig {
}

运行课程:

package bakery;

import bakery.config.BakeryConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Bakery {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BakeryConfig.class);
        String[] beans  = context.getBeanDefinitionNames();
        Taster taster = (Taster) context.getBean("taster");
        taster.taste();
    }
}

测试类:

package bakery;

import bakery.config.BakeryConfig;
import bakery.intrface.Dessert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.assertNotNull;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BakeryConfig.class)
public class BakeryTest {

    @Autowired
    Dessert dessert;

    @Autowired
    Taster taster;

    @Test
    public void contextInit(){
        assertNotNull(dessert);
        dessert.introduce();
    }

    @Test
    public void tasterInit(){
        assertNotNull(taster);
    }
}

当我运行测试时,我得到了异常:没有定义类型为[bakery.intrface.Dessert]的限定bean:期望的单个匹配bean但找到3:cookie,iceCream,cake。

2 个答案:

答案 0 :(得分:2)

有3"甜点"在应用程序上下文中,您必须指定要连接的bean。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = BakeryConfig.class)
public class BakeryTest {

    @Autowired
    @Qualifier("iceCream")  // <===================== you must specify which bean to be wired
    Dessert dessert;

    @Autowired
    Taster taster;

答案 1 :(得分:1)

这是可以预期的。

声明

@Autowired
Dessert dessert;

要求Dessert个对象。 Dessert是界面,有三个实施类CookieIceCreamCake。由于您还没有明确指出您想要的哪些实现,因此Spring会抛出错误,因为它无法决定该怎么做。

如果您在测试中需要此项,则可以执行以下操作之一:

@Autowired
@Qualifier("iceCream")
Dessert dessert;

只获得冰淇淋甜点,

OR

@Autowired
List<Dessert> desserts;

获取包含所有实现的列表。