373 Stimmen

Füllen von Spring @Value während des Unit Tests

Ich versuche, einen Unittest für einen einfachen Bean zu schreiben, der in meinem Programm verwendet wird, um Formulare zu validieren. Der Bean ist mit @Component annotiert und hat eine Klassenvariable, die mit

@Value("${this.property.value}") private String thisProperty; 

initialisiert wird. Ich möchte Unittests für die Validierungsmethoden innerhalb dieser Klasse schreiben, aber wenn möglich möchte ich dies tun, ohne die properties-Datei zu nutzen. Mein Gedanke dahinter ist, dass sich mein Unittest nicht ändern soll, wenn sich der Wert ändert, den ich aus der properties-Datei hole. Mein Unittest testet den Code, der den Wert validiert, nicht den Wert selbst.

Gibt es eine Möglichkeit, Java-Code in meiner Testklasse zu verwenden, um eine Java-Klasse zu initialisieren und die Spring-@Value-Eigenschaft in dieser Klasse zu befüllen, um damit zu testen?

Ich habe diese Anleitung gefunden, die ähnlich ist, aber immer noch eine properties-Datei verwendet. Ich hätte es lieber komplett in Java-Code.

8voto

ahll Punkte 2163
@ExtendWith(SpringExtension.class)    // @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class)

Das könnte hilfreich sein. Der Schlüssel ist, dass ConfigDataApplicationContextInitializer alle Eigenschaftsdaten erhält

6voto

Es ist eine ziemlich alte Frage, und ich bin mir nicht sicher, ob es zu dieser Zeit eine Option war, aber das ist der Grund, warum ich den DependencyInjection immer über den Konstruktor als über den Wert bevorzuge.

Ich kann mir vorstellen, dass Ihre Klasse so aussehen könnte:

class ExampleClass{

   @Autowired
   private Dog dog;

   @Value("${this.property.value}") 
   private String thisProperty;

   ...andere Sachen...
}

Sie können es ändern zu:

class ExampleClass{

   private Dog dog;
   private String thisProperty;

   //optional @Autowire
   public ExampleClass(final Dog dog, @Value("${this.property.value}") final String thisProperty){
      this.dog = dog;
      this.thisProperty = thisProperty;
   }

   ...andere Sachen...
}

Mit dieser Implementierung wird Spring automatisch wissen, was einzufügen ist, aber für Unittests können Sie tun, was auch immer Sie brauchen. Zum Beispiel alle Abhängigkeiten mit Spring autowiren und sie manuell über den Konstruktor injizieren, um eine "ExampleClass"-Instanz zu erstellen, oder nur Spring mit einer Test-Properties-Datei verwenden, oder gar kein Spring verwenden und alle Objekte selbst erstellen.

5voto

fjkjava Punkte 1154

Das Hinzufügen von PropertyPlaceholderConfigurer in der Konfiguration funktioniert für mich.

@Configuration
@ComponentScan
@EnableJpaRepositories
@EnableTransactionManagement
public class TestConfiguration {
    @Bean
    public DataSource dataSource() {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        builder.setType(EmbeddedDatabaseType.DERBY);
        return builder.build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setDataSource(dataSource());
        entityManagerFactoryBean.setPackagesToScan(new String[] { "com.test.model" });
        // Verwenden von Hibernate
        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
        entityManagerFactoryBean.setJpaProperties(getHibernateProperties());
        return entityManagerFactoryBean;
    }

    private Properties getHibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.show_sql", "false");
        properties.put("hibernate.dialect", "org.hibernate.dialect.DerbyDialect");
        properties.put("hibernate.hbm2ddl.auto", "update");
        return properties;
    }

    @Bean
    public JpaTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
         transactionManager.setEntityManagerFactory(
              entityManagerFactory().getObject()
         );

         return transactionManager;
    }

    @Bean
    PropertyPlaceholderConfigurer propConfig() {
        PropertyPlaceholderConfigurer placeholderConfigurer = new PropertyPlaceholderConfigurer();
        placeholderConfigurer.setLocation(new ClassPathResource("application_test.properties"));
        return placeholderConfigurer;
    }
}

Und in der Testklasse

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfiguration.class)
public class DataServiceTest {

    @Autowired
    private DataService dataService;

    @Autowired
    private DataRepository dataRepository;

    @Value("${Api.url}")
    private String baseUrl;

    @Test
    public void testUpdateData() {
        List datas = (List) dataRepository.findAll();
        assertTrue(datas.isEmpty());
        dataService.updateDatas();
        datas = (List) dataRepository.findAll();
        assertFalse(datas.isEmpty());
    }
}

2voto

Siddharth Aadarsh Punkte 131

Ich habe den folgenden Code verwendet und es hat für mich funktioniert:

@InjectMocks
private ClassNotify classNotify;

@BeforeEach
  void init() {
    closeable = MockitoAnnotations.openMocks(this);
    ReflectionTestUtils.setField(classNotify, "EventType", "test-event");

  }

1voto

Camilo Melges Punkte 53

Im Frühling 2.4.1 habe ich einfach die Annotation @SpringBootTest in meinem Test hinzugefügt und offensichtlich spring.profiles.active = test in meiner src/test/resources/application.yml festgelegt.

Ich verwende @ExtendWith({SpringExtension.class}) und @ContextConfiguration(classes = {RabbitMQ.class, GenericMapToObject.class, ModelMapper.class, StringUtils.class}) für externe Konfigurationen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X