Tes JUnit lolos di Eclipse tetapi gagal di Maven Surefire


99

Saya telah menulis beberapa tes JUnit menggunakan JUnit 4 dan perpustakaan uji musim semi. Ketika saya menjalankan tes di dalam Eclipse kemudian berjalan dengan baik dan lulus. Tetapi ketika saya menjalankannya menggunakan Maven (selama proses pembuatan), mereka gagal memberikan kesalahan terkait pegas. Saya tidak yakin apa yang menyebabkan masalah, JUnit, Surefire, atau Spring. Berikut adalah kode pengujian saya, konfigurasi pegas dan pengecualian yang saya dapatkan dari Maven:

PersonServiceTest.java

package com.xyz.person.test;

import static com.xyz.person.util.FjUtil.toFjList;
import static junit.framework.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.util.List;

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.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

import com.xyz.person.bo.Person;
import com.xyz.person.bs.PersonService;

import fj.Effect;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath*:personservice-test.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
public class PersonServiceTest {

    @Autowired
    private PersonService service;

    @Test
    @Transactional
    public void testCreatePerson() {
        Person person = new Person();
        person.setName("abhinav");
        service.createPerson(person);

        assertNotNull(person.getId());
    }

    @Test
    @Transactional
    public void testFindPersons() {
        Person person = new Person();
        person.setName("abhinav");
        service.createPerson(person);

        List<Person> persons = service.findPersons("abhinav");
        toFjList(persons).foreach(new Effect<Person>() {
            public void e(final Person p) {
                assertEquals("abhinav", p.getName());
            }});
    }

}

personervice-test.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:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <import resource="classpath:/personservice.xml" />

    <bean id="datasource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource"
        lazy-init="true">
        <property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
        <property name="url" value="jdbc:derby:InMemoryDatabase;create=true" />
    </bean>

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="datasource" />
        <property name="persistenceUnitName" value="PersonService" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="databasePlatform" value="org.hibernate.dialect.DerbyDialect" />
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
            </bean>
        </property>
        <property name="jpaPropertyMap">
            <map>
                <entry key="hibernate.validator.autoregister_listeners" value="false" />
                <entry key="javax.persistence.transactionType" value="RESOURCE_LOCAL" />
            </map>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="datasource" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"
        proxy-target-class="false" />

    <bean id="beanMapper" class="org.dozer.DozerBeanMapper">
        <property name="mappingFiles">
            <list>
                <value>personservice-mappings.xml</value>
            </list>
        </property>
    </bean>

</beans>

Pengecualian di Maven

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.xyz.person.test.PersonServiceTest
23:18:51,250  WARN JDBCExceptionReporter:77 - SQL Warning: 10000, SQLState: 01J01
23:18:51,281  WARN JDBCExceptionReporter:78 - Database 'InMemoryDatabase' not created, connection made to existing database instead.
23:18:52,937  WARN JDBCExceptionReporter:77 - SQL Warning: 10000, SQLState: 01J01
23:18:52,937  WARN JDBCExceptionReporter:78 - Database 'InMemoryDatabase' not created, connection made to existing database instead.
23:18:52,953  WARN TestContextManager:429 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] to process 'after' execution for test: method [public void com.xyz.person.test.PersonServiceTest.testCreatePerson()], instance [com.xyz.person.test.PersonServiceTest@1bc81bc8], exception [org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access.]
java.lang.IllegalStateException: No value for key [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean@3f563f56] bound to thread [main]
        at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:199)
        at org.springframework.orm.jpa.JpaTransactionManager.doCleanupAfterCompletion(JpaTransactionManager.java:489)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.cleanupAfterCompletion(AbstractPlatformTransactionManager.java:1011)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:804)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.endTransaction(TransactionalTestExecutionListener.java:515)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener.endTransaction(TransactionalTestExecutionListener.java:290)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener.afterTestMethod(TransactionalTestExecutionListener.java:183)
        at org.springframework.test.context.TestContextManager.afterTestMethod(TestContextManager.java:426)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:90)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
        at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:599)
        at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
        at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
23:18:53,078  WARN TestContextManager:377 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener@359a359a] to process 'before' execution of test method [public void com.xyz.person.test.PersonServiceTest.testFindPersons()] for test instance [com.xyz.person.test.PersonServiceTest@79f279f2]
org.springframework.transaction.IllegalTransactionStateException: Pre-bound JDBC Connection found! JpaTransactionManager does not support running within DataSourceTransactionManager if told to manage the DataSource itself. It is recommended to use a single JpaTransactionManager for all transactions on a single DataSource, no matter whether JPA or JDBC access.
        at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:304)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener$TransactionContext.startTransaction(TransactionalTestExecutionListener.java:507)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener.startNewTransaction(TransactionalTestExecutionListener.java:269)
        at org.springframework.test.context.transaction.TransactionalTestExecutionListener.beforeTestMethod(TransactionalTestExecutionListener.java:162)
        at org.springframework.test.context.TestContextManager.beforeTestMethod(TestContextManager.java:374)
        at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
        at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:115)
        at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:102)
        at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
        at java.lang.reflect.Method.invoke(Method.java:599)
        at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
        at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
Tests run: 3, Failures: 0, Errors: 3, Skipped: 0, Time elapsed: 15.625 sec <<< FAILURE!

Results :

Tests in error:
  testCreatePerson(com.xyz.person.test.PersonServiceTest)
  testCreatePerson(com.xyz.person.test.PersonServiceTest)
  testFindPersons(com.xyz.person.test.PersonServiceTest)

Tests run: 3, Failures: 0, Errors: 3, Skipped: 0

Apakah Anda memiliki konfigurasi khusus dari plugin surefire di POM Anda?
matt b

@matt Saya tidak memiliki konfigurasi yang pasti di pom saya
Abhinav Sarkar

1
Saya datang ke artikel ini karena saya memiliki masalah yang sama, tetapi dalam kasus saya, saya menggunakan solusi lain. Setelah mengaktifkan log DEBUG pada pengujian saya, saya menemukan bahwa Spring Framework sedang melihat nama database MongoDB lama, dan nama ini ditetapkan dalam versi lama dari jar yang dibuat oleh proyek lain di ruang kerja saya (meskipun itu dibangun beberapa kali dengan nama baru). Beberapa Maven Clen + menghapus pustaka di .m2 saya diikuti oleh Instalasi Maven dari semua proyek tersebut memecahkan masalah. Meskipun tidak ada alasan bagi proyek untuk melihat toples tua (sayangnya disimpan di suatu tempat)
Cotta

Jawaban:


108

Saya memiliki masalah yang sama (tes JUnit gagal di Maven Surefire tetapi lolos di Eclipse) dan berhasil menyelesaikannya dengan mengatur forkMode untuk selalu dalam konfigurasi maven surefire di pom.xml:

<plugin>
    <groupId> org.apache.maven.plugins </groupId>
    <artifactId> maven-surefire-plugin </artifactId>
    <version> 2.12 </version>
    <configuration>
        <forkMode> selalu </forkMode>
    </configuration>
</plugin>

Parameter yang pasti: http://maven.apache.org/plugins/maven-surefire-plugin/test-mojo.html

Edit (Januari 2014):

Seperti yang ditunjukkan oleh Peter Perháč , parameter forkMode tidak digunakan lagi sejak Surefire 2.14. Mulai dari Surefire 2.14 gunakan ini sebagai gantinya:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.16</version>
    <configuration>
        <reuseForks>false</reuseForks>
        <forkCount>1</forkCount>
    </configuration>
</plugin>

Untuk informasi lebih lanjut, lihat Opsi Fork dan Eksekusi Tes Paralel


Terima kasih! Memperbaiki masalah untuk saya. Tahu kenapa?
Alex

6
Senang mendengarnya. Dalam kasus saya, masalahnya sangat mungkin bahwa file konfigurasi yang dibaca oleh tes JUnit tetap berada di memori, merusak hasil tes selanjutnya. Jika forkMode disetel ke true, setiap kelas pengujian dijalankan sepenuhnya secara independen, yang menjamin bahwa pengujian dijalankan tanpa efek samping.
simon

4
baru saja mencoba ini menggunakan surefire 2.16 dan mendapatkan: "Parameter forkMode tidak digunakan lagi sejak versi 2.14. Gunakan forkCount dan reuseForks sebagai gantinya." jadi berhati-hatilah ini hanya bekerja pada sebelum 2.14
Peter Perháč

1
Kemungkinan besar Anda dapat menggunakan jumlah garpu yang lebih tinggi, yang penting di sini adalah bahwa garpu tidak digunakan kembali dan satu garpu akan membuat pembuatan paket membutuhkan waktu yang sangat lama.
Sandy Simonton

1
Ditambah satu untuk memperbarui jawaban Anda dua tahun kemudian
Gerben Rampaart

7

Saya tiba-tiba mengalami kesalahan ini, dan solusi bagi saya adalah menonaktifkan untuk menjalankan tes secara paralel.

Jarak tempuh Anda mungkin berbeda, karena saya dapat menurunkan jumlah pengujian yang gagal dengan mengkonfigurasi yang pasti untuk menjalankan pengujian paralel berdasarkan ´classes´ .:

            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.7.2</version>
                <configuration>
                    <parallel>classes</parallel>
                    <threadCount>10</threadCount>
                </configuration>
            </plugin>

Seperti yang saya tulis pertama kali, ini tidak cukup untuk rangkaian pengujian saya, jadi saya sepenuhnya menonaktifkan paralel dengan menghapus <configuration>bagian tersebut.


7

Saya memiliki masalah yang sama, penjelasan @Autowireddalam kode pengujian tidak berfungsi dengan menggunakan baris perintah Maven sementara itu berfungsi dengan baik di Eclipse. Saya baru saja memperbarui versi JUnit saya dari 4.4 menjadi 4.9 dan masalahnya telah terpecahkan.

<dependency>
    <groupId>junit</groupId
    <artifactId>junit</artifactId>
    <version>4.9</version>
</dependency>

5

Ini tidak berlaku untuk situasi Anda, tetapi saya memiliki hal yang sama - tes yang akan lulus di Eclipse gagal saat tujuan uji coba dari Maven dijalankan.

Ternyata itu adalah tes sebelumnya di suite saya, dalam paket yang berbeda . Ini membutuhkan waktu seminggu untuk menyelesaikannya!

Pengujian sebelumnya menguji beberapa kelas Logback, dan membuat konteks Logback dari file konfigurasi.

Tes selanjutnya adalah menguji subkelas SimpleRestTemplate Spring, dan entah bagaimana, konteks Logback sebelumnya diadakan, dengan DEBUG aktif. Ini menyebabkan panggilan ekstra dilakukan di RestTemplate untuk mencatat HttpStatus, dll.

Memeriksa apakah seseorang pernah masuk ke dalam situasi ini adalah hal lain. Saya memperbaiki masalah saya dengan menyuntikkan beberapa Mock ke dalam kelas pengujian Logback saya, sehingga tidak ada konteks Logback nyata yang dibuat.


Terima kasih atas penunjuknya. Saya mengalami masalah serupa di mana proyek maven default memiliki kasus uji tradisional yang dibuat secara otomatis (yang saya abaikan) sedangkan saya menggunakan SpringJUnit4ClassRunner untuk kasus uji baru saya. Menambahkan anotasi SpringJUnit4ClassRunner ke pengujian yang dibuat secara otomatis memecahkan masalah saya.
Avnish

5

Saya memiliki masalah yang sama, tetapi dengan IntelliJ IDEA + Maven + TestNG + spring-test. ( uji musim semi sangat penting tentu saja :)) Telah diperbaiki ketika saya mengubah konfigurasi maven-surefire-plugin untuk menonaktifkan pengujian yang dijalankan secara paralel. Seperti ini:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.9</version>
    <configuration>
        <skipTests>${maven.test.skip}</skipTests>
        <trimStackTrace>false</trimStackTrace>
        <!--<parallel>methods</parallel>-->
        <!-- to skip integration tests -->
        <excludes>
            <exclude>**/IT*Test.java</exclude>
            <exclude>**/integration/*Test.java</exclude>
        </excludes>
    </configuration>
    <executions>
        <execution>
            <id>integration-test</id>
            <phase>integration-test</phase>
            <goals>
                <goal>test</goal>
            </goals>
            <configuration>
                <skipTests>${maven.integration-test.skip}</skipTests>
                <!-- Make sure to include this part, since otherwise it is excluding Integration tests -->
                <excludes>
                    <exclude>none</exclude>
                </excludes>
                <includes>
                    <include>**/IT*Test.java</include>
                    <include>**/integration/*Test.java</include>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

4

Hasil eksekusi uji berbeda dari JUnit rundan darimaven install tampaknya menjadi gejala dari beberapa masalah.

Menonaktifkan eksekusi uji penggunaan ulang thread juga menghilangkan gejala dalam kasus kami, tetapi kesan bahwa kode tersebut tidak aman untuk thread masih kuat.

Dalam kasus kami, perbedaannya disebabkan oleh adanya kacang yang mengubah perilaku pengujian. Menjalankan pengujian JUnit saja akan baik-baik saja, tetapi menjalankan proyekinstall target akan mengakibatkan kasus pengujian yang gagal. Karena itu adalah kasus uji yang sedang dikembangkan, itu langsung mencurigakan.

Ini menghasilkan kasus uji lain yang membuat contoh kacang melalui Spring yang akan bertahan sampai eksekusi kasus uji baru. Kehadiran kacang memodifikasi perilaku beberapa kelas dan menghasilkan hasil yang gagal.

Solusi dalam kasus kami adalah menyingkirkan kacang, yang tidak diperlukan sejak awal (hadiah lain dari salinan + tempel) pistol ).

Saya menyarankan semua orang dengan gejala ini untuk menyelidiki apa akar penyebabnya. Menonaktifkan penggunaan ulang thread dalam eksekusi pengujian mungkin hanya menyembunyikannya.


3

Saya mengalami masalah yang sama, tetapi masalah bagi saya adalah bahwa pernyataan Java (misalnya assert (num> 0)) tidak diaktifkan untuk Eclipse, tetapi diaktifkan saat menjalankan maven.

Oleh karena itu, menjalankan tes jUnit dari Eclipse tidak menangkap memicu kesalahan pernyataan.

Ini diperjelas saat menggunakan jUnit 4.11 (berlawanan dengan versi lama yang saya gunakan) karena mencetak kesalahan pernyataan, mis.

java.lang.AssertionError: null
    at com.company.sdk.components.schema.views.impl.InputViewHandler.<init>(InputViewHandler.java:26)
    at test.com.company.sdk.util.TestSchemaExtractor$MockInputViewHandler.<init>(TestSchemaExtractor.java:31)
    at test.com.company.sdk.util.TestSchemaExtractor.testCreateViewToFieldsMap(TestSchemaExtractor.java:48)

dalam hal ini, tautan ini relevan: confluence.atlassian.com/display/JIRAKB/…
OhadR

... dan dalam kasus gradle, tambahkan ini: test {enableAssertions = false ignoreFailures = true}
OhadR

3

Saya memiliki masalah serupa dengan penyebab yang berbeda dan karena itu solusi yang berbeda. Dalam kasus saya, saya benar-benar mengalami kesalahan di mana objek tunggal memiliki variabel anggota yang dimodifikasi dengan cara yang tidak aman. Dalam hal ini, mengikuti jawaban yang diterima dan menghindari pengujian paralel hanya akan menyembunyikan kesalahan yang sebenarnya diungkapkan oleh tes tersebut. Solusi saya, tentu saja, adalah memperbaiki desain sehingga saya tidak memiliki perilaku buruk ini dalam kode saya.


2

[Saya tidak yakin ini adalah jawaban untuk pertanyaan asli, karena stacktrace di sini terlihat sedikit berbeda, tetapi mungkin berguna bagi orang lain.]

Anda bisa mendapatkan tes yang gagal di Surefire saat Anda juga menjalankan Cobertura (untuk mendapatkan laporan cakupan kode). Ini karena Cobertura membutuhkan proxy (untuk mengukur penggunaan kode) dan ada semacam konflik antara keduanya dan proxy Spring. Ini hanya terjadi saat Spring menggunakan cglib2, yang akan terjadi jika, misalnya, Anda punyaproxy-target-class="true" , atau jika Anda memiliki objek yang sedang di-proxy-kan yang tidak mengimplementasikan antarmuka.

Perbaikan normal untuk ini adalah menambahkan antarmuka. Jadi, misalnya, DAO harus berupa antarmuka, yang diimplementasikan oleh kelas DAOImpl. Jika Anda memasang autowire pada antarmuka, semuanya akan berfungsi dengan baik (karena cglib2 tidak lagi diperlukan; proxy JDK yang lebih sederhana ke antarmuka dapat digunakan sebagai gantinya dan Cobertura berfungsi dengan baik dengan ini).

Namun, Anda tidak dapat menggunakan antarmuka dengan pengontrol beranotasi (Anda akan mendapatkan kesalahan runtime saat mencoba menggunakan pengontrol di servlet) - Saya tidak memiliki solusi untuk uji Cobertura + Spring yang pengontrol autowire.


2

Saya memiliki masalah serupa: Tes JUnit gagal di Maven Surefire tetapi lolos di Eclipse saat saya menggunakan library JUnit versi 4.11.0 dari SpringSource Bundle Repository. Khusus:

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

Kemudian saya menggantinya dengan mengikuti JUnit library versi 4.11 dan semuanya berfungsi dengan baik.

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
</dependency>

Ini melakukan trik untuk saya. Pengujian saya langsung berjalan saat saya menjalankan Maven dari baris perintah. Namun, di Eclipse, saya harus menutup dan membuka kembali proyek sebelum pengujian unit dijalankan di jendela JUnit.
Marvo

1

Saya mengalami masalah ini hari ini menguji metode yang mengonversi objek yang berisi Mapstring JSON. Saya berasumsi bahwa Eclipse dan plugin pasti Maven menggunakan JRE berbeda yang memiliki implementasi HashMappengurutan yang berbeda atau semacamnya, yang menyebabkan pengujian yang dijalankan melalui Eclipse lulus dan pengujian yang dijalankan pasti gagal ( assertEqualsgagal). Solusi termudah adalah dengan menggunakan implementasi Peta yang memiliki pemesanan yang andal.


0

Anda tidak perlu memasukkan DataSource di JpaTransactionManager karena EntityManagerFactory sudah memiliki sumber data. Coba yang berikut ini:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
   <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

Tes gagal (dengan kesalahan) di Eclipse jika saya menghapus sumber data dari kacang transactionManager.
Abhinav Sarkar

0

Biasanya ketika tes lulus dalam gerhana dan gagal dengan maven, itu adalah masalah jalur kelas karena itu adalah perbedaan utama antara keduanya.

Jadi, Anda dapat memeriksa classpath dengan maven -X test dan memeriksa classpath dari eclipse melalui menu atau di file .classpath di root project Anda.

Apakah Anda yakin misalnya bahwa personervice-test.xml ada di classpath?


Ya, karena saya dapat melihat log INFO dari konteks Spring yang dimuat di konsol selama pengujian maven dijalankan.
Abhinav Sarkar

0

Ini telah membantu saya dalam memecahkan masalah saya. Saya memiliki gejala serupa di mana maven akan gagal namun menjalankan tes junit berjalan dengan baik.

Ternyata pom.xml orang tua saya berisi definisi berikut:

    <plugin>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.9</version>
      <configuration>
        <forkMode>pertest</forkMode>
        <argLine>-Xverify:none</argLine>
      </configuration>
    </plugin>

Dan dalam proyek saya, saya menggantinya untuk menghapus argLine:

    <plugin>
       <artifactId>maven-surefire-plugin</artifactId>
       <configuration>
            <forkMode>pertest</forkMode>
            <argLine combine.self="override"></argLine>
          </configuration>
    </plugin>

Semoga ini akan membantu seseorang dalam memecahkan masalah plugin jitu.



0

Saya memiliki masalah yang sama, dan solusi bagi saya adalah mengizinkan Maven menangani semua dependensi, termasuk toples lokal. Saya menggunakan Maven untuk dependensi online, dan mengonfigurasi jalur build secara manual untuk dependensi lokal. Jadi, Maven tidak mengetahui dependensi yang saya konfigurasikan secara manual.

Saya menggunakan solusi ini untuk menginstal dependensi jar lokal ke Maven:

Bagaimana cara menambahkan file jar lokal di proyek maven?


0

Dalam kasus saya, alasannya adalah bug dalam kode. Tes ini mengandalkan urutan elemen tertentu di a HashSet, yang ternyata berbeda saat dijalankan di Eclipse atau di Maven Surefire.


-2

Kemungkinan besar file konfigurasi Anda ada di src / main / resources , sementara file tersebut harus di bawah src / test / resources agar berfungsi dengan baik di bawah maven.

https://cwiki.apache.org/UIMA/differences-between-running-unit-tests-in-eclipse-and-in-maven.html

Saya membalas ini setelah dua tahun karena saya tidak dapat menemukan jawaban ini di sini dan saya pikir itu adalah jawaban yang benar.


Tidak, itu sebaliknya. src/main/resourcesterlihat untuk pengujian, tetapi src/test/resourcestidak terlihat oleh kode produksi.
Christoffer Hammarström

tautan yang Anda tambahkan berbicara tentang ketergantungan antar proyek, bukan dalam main / test dalam proyek yang sama
eis
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.