Spring a prebíjanie automaticky odhalených beanov

Až do Springu 4.1 bolo značne náročné predefinovávať beany, ktoré boli registrované v aplikačnom kontexte automaticky vďaka mechanizmu @ComponentScan. S príchodom Spring Bootu, ktorý registruje mnoho beanov práve týmto spôsobom, sa môže stať, že chceme poskytnúť vlastnú definíciu beanu. Týka sa to najmä testov, hlavne v prípade potreby mockovať beany.

Našťastie, v Springu 4.2 to je už možné, a nie sú s tým žiadne problémy.

Ukážme si príklad.

Vytvorme si jednoduchý projekt, kde do závislostí dodáme Spring, jeho testovací modul a JUnit. Mavenovský POM by vyzeral takto:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.2.4.RELEASE</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Predstavme si jednoduchý bean, ktorý bude zdraviť:

package sk.upjs.ics.novotnyr.spring;

import org.springframework.stereotype.Component;

@Component
public class Greeter {
    public String greet() {
        return "Hello!";
    }
}

Bean odhaľme nasledovným kontextom:

package sk.upjs.ics.novotnyr.spring;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class ApplicationContext {
    // tu nič nie je
}

Kontext naštartujme v samostatnej triede:

package sk.upjs.ics.novotnyr.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Runner {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationContext.class);
        Greeter greetingBean = context.getBean(Greeter.class);

        System.out.println(greetingBean.greet());
    }
}

Výsledkom bude, prirodzene:

Hello!

Čo ak chceme prebiť implementáciu v teste?

Vyrobme si testovací kontext a predefinujme beanu s názvom greeter, kde budeme vracať španielske pozdravy.

@Configuration
public class TestApplicationContext {
   @Bean
   Greeter greeter() {
       return new Greeter() {
           @Override
           public String greet() {
               return "Hola!";
           }
       };
   }
}

Vytvorme si na to test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestApplicationContext.class, ApplicationContext.class })
public class GreeterTest {
    @Autowired
    private Greeter greeter;

    @Test
    public void test() throws Exception {
        Assert.assertEquals("Hola!", greeter.greet());
    }
}

Ak ho spustíme, uvidíme kľúčovú hlášku:

INFO: Overriding bean definition for bean 'greeter' with a different definition...

Týmto Spring oznámi, že namiesto automaticky odhaleného greetera použije prekrytý bean z testovacieho kontextu.. a hop! máme španielsky pozdrav.

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *