2012-09-21 32 views
8

Sử dụng Spring 3.1.2, JUnit 4.10.0 và khá mới đối với cả hai phiên bản. Tôi đang gặp sự cố khiến tôi không thể sử dụng tính năng autowiring dựa trên chú thích.Tự động không hoạt động trong Mùa xuân 3.1.2, JUnit 4.10.0

Dưới đây là hai mẫu, một mẫu không sử dụng chú thích đang hoạt động tốt. Và thứ hai sử dụng chú thích, không hoạt động và tôi không tìm ra lý do. Tôi đã theo dõi các mẫu thử nghiệm mùa xuân-mvc khá nhiều.

Làm việc:

package com.company.web.api; 
// imports 

public class ApiTests { 

    @Test 
    public void testApiGetUserById() throws Exception { 
     ApplicationContext ctx = new ClassPathXmlApplicationContext("/com/company/web/api/ApiTests-context.xml"); 
     UserManagementService userManagementService = (UserManagementService) ctx.getBean("userManagementService"); 
     ApiUserManagementController apiUserManagementController = new ApiUserManagementController(userManagementService); 
     MockMvc mockMvc = standaloneSetup(apiUserManagementController).build(); 

     // The actual test  
     mockMvc.perform(get("/api/user/0").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); 
    } 
} 

Không, vì userManagementService là null, không nhận được autowired:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration  // should default to ApiTests-context.xml in same package 
public class ApiTests { 

    @Autowired 
    UserManagementService userManagementService; 

    private MockMvc mockMvc; 

    @Before 
    public void setup(){ 
     // SetUp never gets called?! 
    } 

    @Test 
    public void testGetUserById() throws Exception { 

     // !!! at this point, userManagementService is still null - why? !!!  

     ApiUserManagementController apiUserManagementController 
      = new ApiUserManagementController(userManagementService); 

     mockMvc = standaloneSetup(apiUserManagementController).build(); 

     // The actual test 
     mockMvc.perform(get("/api/user/0").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); 
    } 
} 

Lưu ý rằng cả hai lớp học thử nghiệm trên nên sử dụng cấu hình bối cảnh tương tự, và userManagementService được định nghĩa trong đó.

ApiTests-context.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xmlns:jee="http://www.springframework.org/schema/jee" 
     xsi:schemaLocation=" 
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
      http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd 
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
     <property name="url" value="jdbc:mysql://localhost:3306/mydb?useUnicode=true&amp;characterEncoding=utf8"/> 
     <property name="username" value="user"/> 
     <property name="password" value="passwd"/> 
    </bean> 

    <!-- Hibernate SessionFactory --> 
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" 
      p:dataSource-ref="dataSource" p:mappingResources="company.hbm.xml"> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
       <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> 
       <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop> 
      </props> 
     </property> 
     <property name="eventListeners"> 
      <map> 
       <entry key="merge"> 
        <bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/> 
       </entry> 
      </map> 
     </property> 
    </bean> 

    <!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) --> 
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
      p:sessionFactory-ref="sessionFactory"/> 

    <!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= --> 

    <context:annotation-config/> 
    <tx:annotation-driven/> 
    <context:mbean-export/> 

    <!-- tried both this and context:component-scan --> 
    <!--<bean id="userManagementService" class="com.company.web.hibernate.UserManagementServiceImpl"/>--> 
    <context:component-scan base-package="com.company"/> 

    <!-- Hibernate's JMX statistics service --> 
    <bean name="application:type=HibernateStatistics" class="org.hibernate.jmx.StatisticsService" autowire="byName"/> 

</beans> 

và UserManagementService (giao diện) cũng như UserManagementServiceImpl có @Service chú thích.

Hai câu hỏi/quan sát nhỏ: setup() không bao giờ được gọi, mặc dù nó có chú thích @Trước. Hơn nữa, tôi nhận thấy rằng các phương pháp thử nghiệm của tôi không được thực hiện/nhận ra nếu chúng không bắt đầu với tên 'test', mà không phải là trường hợp mặc dù với tất cả các mẫu thử nghiệm-spring-mvc tôi đã thấy.

pom.xml:

<dependency> 
     <groupId>org.junit</groupId> 
     <artifactId>com.springsource.org.junit</artifactId> 
     <version>4.10.0</version> 
     <scope>test</scope> 
    </dependency> 

enter image description here

Cập nhật:

Vấn đề chỉ xảy ra khi tôi chạy thử nghiệm từ maven; ok khi tôi chạy thử nghiệm từ bên trong IDE của tôi (IntelliJ IDEA).

 <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-surefire-plugin</artifactId> 
      <version>2.12.3</version> 
      <configuration> 
       <includes> 
        <include>**/*Tests.java</include> 
       </includes> 
      </configuration> 
     </plugin> 
+0

gì xảy ra nếu bạn sử dụng phong cách chú thích với một explicite tên tập tin cấu hình '@ContextConfiguration ("classpath: com/công ty/web/api/ApiTests -context.xml ")' – Ralph

+2

hãy đăng toàn bộ ngữ cảnh. cũng đăng pom của bạn bởi vì nó có vẻ như bạn đang sử dụng junit 3 bằng cách nào đó? – MikePatel

+0

@Ralph Đã thử nó rồi, không có sự khác biệt. @ContextConfiguration (locations = {"classpath: công ty/com/web/api/ApiTests-context.xml"}) –

Trả lời

6

Tự động không xảy ra trừ khi bạn thực hiện quét thành phần.

Tại sao bạn nhận xét nó trong mã của bạn?

<!--<context:component-scan base-package="com.company"/>--> 

Ngoài ra còn lại: junit. Nếu bạn đang ở nhật thực, bạn có thể vào khung nhìn cây phụ thuộc của pom và lọc trên junit. Kiểm tra bạn đang thực sự sử dụng phiên bản đó và không kéo trong một junit cũ hơn.

Chỉnh sửa: Ok Tôi vừa kiểm tra cấu hình của bạn và có thể làm cho nó hoạt động bên này.Đoán duy nhất của tôi có thể là bạn đang bằng cách nào đó chạy nó với một Á hậu thử nghiệm xấu mà gây ra nó để sử dụng sai junit.

Chỉnh sửa 2 (SOLVED): Vì vậy, hóa ra vấn đề là vì bạn đang sử dụng phiên bản tùy chỉnh của junit. Chắc chắn sẽ tìm thư viện junit được cung cấp và không thể tìm thấy nó. Kết quả là nó mặc định là junit 3, đó là nguyên nhân khiến ứng dụng của bạn bỏ qua việc tải cấu hình.

Bạn explictly có thể chỉ định các nhà cung cấp tùy chỉnh như

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-surefire-plugin</artifactId> 
    <version>2.12.3</version> 
    <dependencies> 
     <dependency> 
     <groupId>org.apache.maven.surefire</groupId> 
     <artifactId>surefire-junit47</artifactId> 
     <version>2.12.3</version> 
     </dependency> 
    </dependencies> 
    </plugin> 

Nhưng tôi đã phát hiện ra rằng nó không hoạt động tốt với các hợp đồng mua tùy chỉnh. Nếu có thể tôi sẽ đề nghị sử dụng phiên bản tiêu chuẩn của junit.

+0

Tôi đã thử nghiệm cả hai thành phần quét cũng như đặt đậu trong đó bằng tay. Sẽ không giống như vậy? Nhưng dù sao, không phải cách nào cũng hoạt động, cũng như khi tôi sử dụng quét thành phần. Tôi không có trong Eclipse, tôi đang ở IntelliJ IDEA. Ngoài ra còn có một cây phụ thuộc và nó hiển thị cho tôi org.junit: com.springsource.org.junit: 4.10.0 –

+0

Tôi đã thay đổi các câu hỏi/mã trên thành thành phần quét (không nhận xét thêm nữa) một lần nữa. Như đã đề cập, tôi đã thử điều đó trước đây, nhưng vẫn không thành công). –

+0

Tôi sử dụng SpringJUnit4ClassRunner - bạn có ý đó không? Đó là thứ họ sử dụng ở khắp mọi nơi http://rstoyanchev.github.com/spring-31-and-mvc-test/#26 –

0

Hãy thử cấu hình ngữ cảnh cụ thể, ví dụ:

@ContextConfiguration(locations = {"/file1.xml", "/file2.xml" }) 

(chỉ hiển thị như thế nào điều này có thể được sử dụng với nhiều file khi cần thiết - một trong những có thể đủ)

Chỉnh sửa: Bạn đã kích hoạt AutowiredAnnotationBeanPostProcessor như đã đề cập ở đây? http://www.mkyong.com/spring/spring-auto-wiring-beans-with-autowired-annotation/

+0

Đã thử, không có sự khác biệt, xem câu hỏi được cập nhật ở trên. –

0

Tôi gặp vấn đề tương tự. My @Autowire sẽ làm việc trong IDE của tôi (SpringSource STS) nhưng sẽ không tải được ngữ cảnh ứng dụng khi tôi đang sử dụng Maven để xây dựng từ dòng lệnh.

Vấn đề là với các phụ thuộc của tôi trong tệp pom.xml. Tôi đã sử dụng phiên bản Spring của JUnit gây ra lỗi. Tôi nghĩ rằng đây là nguyên nhân gốc rễ của bài đăng gốc. Tôi không phải mã bất kỳ plugin Maven nào cho nó hoạt động.

tôi đã thay đổi

<dependency> 
    <groupId>org.junit</groupId> 
    <artifactId>com.springsource.org.junit</artifactId> 
    <version>4.7.0</version> 
</dependency> 

để

<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>4.10</version> 
</dependency> 
Các vấn đề liên quan