2017-07-27 22 views
6

Spring boot Rest denetleyicisi için bir test yapıyorum. Bu dinlenme denetleyicisi bazı değerleri db'ye yazar.Rest denetleyicileri için test yazmak için in-memory db kullanın

Bu test için Spring'in sağladığı bellek içi veritabanını kullanmak istiyorum.

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Failed to replace DataSource with an embedded database for tests. If you want an embedded database please put a supported one on the classpath or tune the replace attribute of @AutoconfigureTestDatabase.

Bu: daha aşağı Aşağıdaki özel durum bkz hata yığın izleme

java.lang.IllegalStateException: Failed to load ApplicationContext 

: this doc göre bu hataya neden olur @DataJpaTest, test sınıfı açıklama zorunda Üzerinde çalıştığım test sınıfı:

@RunWith(SpringRunner.class) 
@SpringBootTest 
@AutoConfigureMockMvc 
@DataJpaTest 
public class AuthenticationControllerFTest { 

    @Autowired 
    private MockMvc mockMvc; 

    @MockBean 
    private AuthenticationManager authenticationManager; 

    @Autowired 
    private WebApplicationContext context; 

    @Autowired 
    private Filter springSecurityFilterChain; 

    @Before 
    public void setup() { 
     mockMvc = MockMvcBuilders.webAppContextSetup(context) 
       .addFilters(springSecurityFilterChain).build(); 
    } 

    @Test 
    public void testCreate() throws Exception { 

     String exampleUserInfo = "{\"name\":\"Salam12333\",\"username\":\"[email protected]\",\"password\":\"Salam12345\"}"; 
     RequestBuilder requestBuilder = MockMvcRequestBuilders 
       .post("/signup") 
       .accept(MediaType.APPLICATION_JSON).content(exampleUserInfo) 
       .contentType(MediaType.APPLICATION_JSON); 

     MvcResult result = mockMvc.perform(requestBuilder).andReturn(); 

     MockHttpServletResponse response = result.getResponse(); 
     int status = response.getStatus(); 
     Assert.assertEquals("http response status is wrong", 200, status); 
    } 
} 

Bu hata neden oluyor?

spring.datasource.username = hello 
spring.datasource.password = hello 
spring.datasource.driver-class-name= com.mysql.jdbc.Driver 
spring.datasource.url = jdbc:mysql://localhost:3306/myproject?useSSL=false 

spring.jpa.show-sql=true 
spring.jpa.hibernate.ddl-auto=update 
logging.level.org.hibernate.SQL=DEBUG 
logging.level.org.hibernate.type=TRACE 
logging.level.org.springframework.web=DEBUG 

server.port = 8443 
server.ssl.key-store = classpath:tomcat.keystore 
server.ssl.key-store-password = hello 
server.ssl.key-password = hello 
server.ssl.enabled = true 
server.ssl.key-alias=myproject 

Düzenleme 2

benim pom.xml için aşağıdaki eklendi:

<dependency> 
    <groupId>org.hsqldb</groupId> 
    <artifactId>hsqldb</artifactId> 
    <scope>test</scope> 
</dependency> 

Ben application-test.properties oluşturulan düzenleme 1 Bu

benim application.properties içeriğidir wi

spring.datasource.username= root 
spring.datasource.password= password 
spring.datasource.driver-class-name= org.h2.Driver 
spring.datasource.url= jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 
  1. kullanıcı adı ve passowrd nedir: Aşağıdaki içerik th? Onları nerede ayarlamalıyım?

Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

+0

"Gömülü bir veritabanı istiyorsanız, lütfen desteklenen bir dosyayı sınıf yoluna koyun veya @OtomatikConfigureTestDatabase'in Değiştir özniteliğini ayarlayın. Yani, sınıf yoluna gömülü bir veritabanı koydun mu? –

+0

'application.properties' dosya içeriğimi asıl gönderiye ekliyorum. –

+0

application.properties, sınıf yolunu etkilemez. Pom.xml dosyanıza h2 veya hsqldb eklemeniz gerekir. –

cevap

4

gör javax.sql.DataSource uygulaması. Varsayılan bağlantı URL'si jdbc:h2:mem:testdb ve varsayılan kullanıcı adı ve şifre: kullanıcı adı: sa ve şifre: boş.

uygulama.özellikleri biz hariç hafıza veritabanı yapılandırmasında için ek herhangi bir şey eklemek gerekmez

spring.datasource.url=jdbc:h2:mem:tesdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE 
    spring.datasource.driverClassName=org.h2.Driver 
    spring.datasource.username=sa 
    spring.datasource.password= 

    spring.datasource.testWhileIdle = true 
    spring.datasource.validationQuery = SELECT 1 

    spring.jpa.show-sql = true 
    spring.h2.console.enabled=true // if you need console 

H2 Bağımlılık

<dependency> 
     <groupId>com.h2database</groupId> 
     <artifactId>h2</artifactId> 
     <scope>runtime</scope> 
    </dependency> 

    <dependency> // If you need h2 web console 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 

Sen bahar bagajında ​​içinde yönetim http://localhost:8080/h2-console

+0

"Kullanıcı adı" ve "şifre" değerleri varsayılan mı? değilse, onları nerede ayarlamalıyım? "Çalışma zamanı" kapsamı neden "test" değil? –

+0

@ArianHosseinzadeh Cevabımı güncelledim, Kimlik bilgileri varsayılan, onları h2 konsolunda değiştirebilir, açıkladığıma cevabımı ekledim. Kapsam hakkında emin değilim - çalışma zamanı benim için iyi çalışıyor. Test için değiştirebilirsiniz. – fg78nc

1

hem ek açıklamaları @AutoConfigureMockMvc ve @DataJpaTest çıkarın:

  • Ben de testi çalıştırdığınızda bu çizgiyi içeren bir hata alıyorum test sınıfına @ActiveProfiles("test") eklendi. Tam uygulamayı test etmeye çalışıyorsunuz, bu yüzden @SpringBootTest ek açıklamalarına da ihtiyacınız var. @DataJpaTest sadece, sadece veri uygulama dilimini test etmek istiyorsanız gereklidir. Belki de bu bir yardımcı olur: https://spring.io/blog/2016/04/15/testing-improvements-in-spring-boot-1-4

  • +0

    Ama asıl db'yi kullanmak istemiyorum. Bellek içi db kullanmak istiyorum. –

    +0

    Her iki ek notu da kaldırdığımda şu hatayı alıyorum: ''mockMvc' alanıyla ifade edilen istenmeyen bağımlılık; nested exception org.springframework.beans.factory.NoSuchBeanDefinitionException: "org.springframework.test.web.servlet.MockMvc" türünde hiçbir niteleyici fasulye yok: autowire adayı olarak nitelendirilen en az 1 fasulye bekleniyor. Bağımlılık ek açıklamaları: {@ org.springframework.beans.factory.annotation.Outowired (required = true)} –

    1

    spring.datasource.url=jdbc:hsqldb:mem:testdb 
    spring.datasource.username=sa 
    spring.datasource.password= 
    
    spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect 
    spring.jpa.show-sql=true 
    spring.jpa.hibernate.ddl-auto=create 
    

    Otomatik yapılandırmayı sağlayan @SpringBootApplication ile sınıfını, açıklama ve üzerinde sınıf H2 bağımlılığı olan Spring BootH2 bellek içi veritabanı bağımlılık göreceksiniz (aşağıya bakınız) ve bunun yaratacak varsayarsak da Configure specific in memory database for testing purpose in Spring

    +0

    Ve ilk olarak hsqldb'yi yapılandırmam gerektiğini varsayalım, değil mi? –

    +0

    Java'da "kullanıcıadı", "parola" ve "testdb" oluşturmanın bir yolu var mı? –

    +0

    Veritabanında bellek var ... ne demek 'testdb' oluşturmak? Hazırda bekletme, başlangıçta tablolarınızdan tabloları oluşturacaktır. Değerleri önceden yüklemek istiyorsanız bir SQL komut dosyası kullanmanız gerekir. Başka sorularınız varsa lütfen SO'yu arayın ya da yeni bir soru sorun. –

    2

    için h2 konsoluna erişebilir dosya sınıf yolunda (application.properties) sınıf yolundaki jar dosyası için (src/test/resources, maven kullanılıyorsa) geri kalan şeyler, önyükleme (önyükleme güzelliği) tarafından dikkate alınacaktır.

    Diğer bir seçenek profili özgü özellikler dosyanın ikisi de aşağıda verilmiştir

    Numune yapılandırması özelliği dosya için test yapılandırmaları için geçerlidir

    (örneğin application-test.properties için) sınıf yolunda src/amin/resources dosyasını sağlamaktır (düşünün sınıf yolunda HSQL DB kavanoz): bellek DB, aşağıdaki şeylere ihtiyaç ile Test DİNLENME hizmeti için

    spring.jpa.hibernate.ddl-auto = create-drop 
    spring.jpa.database = HSQL 
    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.HSQLDialect 
    spring.datasource.driverClassName = org.hsqldb.jdbcDriver 
    spring.datasource.url: jdbc:hsqldb:mem:scratchdb 
    spring.datasource.username = sa 
    spring.datasource.password = pass 
    
    2

    :
    1.

    <dependency> 
        <groupId>com.h2database</groupId> 
        <artifactId>h2</artifactId> 
        <scope>runtime</scope> 
        <optional>true</optional> 
    </dependency> 
    

    2. application.properties içinde h2 yapılandırmayı tanımlayın pom.xml'Bu h2 Bağımlılık ekle veya application.yaml

    spring.jpa.database = h2 
    spring.datasource.url=jdbc:hsqldb:mem:testdb 
    spring.datasource.username=sa 
    spring.datasource.password= 
    spring.jpa.database-platform=org.hibernate.dialect.HSQLDialect 
    spring.jpa.show-sql=true 
    spring.jpa.hibernate.ddl-auto=create 
    

    3. Annotatesekmesindeki Eğer sınıf

    @RunWith(SpringRunner.class) 
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
    
    testi

    Tüm kodlar aşağıdaki gibi olacaktır:

    @RunWith(SpringRunner.class) 
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
    public class AuthenticationControllerFTest { 
    
        @Autowired 
        private MockMvc mockMvc; 
    
        @MockBean 
        private AuthenticationManager authenticationManager; 
    
        @Autowired 
        private WebApplicationContext context; 
    
        @Autowired 
        private Filter springSecurityFilterChain; 
    
        @Before 
        public void setup() { 
         mockMvc = MockMvcBuilders.webAppContextSetup(context) 
           .addFilters(springSecurityFilterChain).build(); 
        } 
    
        @Test 
        public void testCreate() throws Exception { 
    
         String exampleUserInfo = "{\"name\":\"Salam12333\",\"username\":\"[email protected]\",\"password\":\"Salam12345\"}"; 
         RequestBuilder requestBuilder = MockMvcRequestBuilders 
           .post("/signup") 
           .accept(MediaType.APPLICATION_JSON).content(exampleUserInfo) 
           .contentType(MediaType.APPLICATION_JSON); 
    
         MvcResult result = mockMvc.perform(requestBuilder).andReturn(); 
    
         MockHttpServletResponse response = result.getResponse(); 
         int status = response.getStatus(); 
         Assert.assertEquals("http response status is wrong", 200, status); 
        } 
    } 
    
    İlgili konular