2016-08-04 38 views
1

失败我有一个类,我不得不测试:测试在IDE及格,但TeamCity的

package com.mycompany.openapi.cms.core.support.liquibase; 

import liquibase.change.custom.CustomTaskChange; 
import liquibase.database.Database; 
import liquibase.database.jvm.JdbcConnection; 
import liquibase.exception.CustomChangeException; 
import liquibase.exception.SetupException; 
import liquibase.exception.ValidationErrors; 
import liquibase.resource.ResourceAccessor; 
import org.slf4j.LoggerFactory; 
import org.springframework.util.StringUtils; 

import java.io.BufferedReader; 
import java.io.FileNotFoundException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.sql.Statement; 
import java.util.Set; 

public class ApplySqlFileIfExistsChange implements CustomTaskChange { 

    private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass()); 

    private String file; 
    private ResourceAccessor resourceAccessor; 

    @Override 
    public void execute(Database database) throws CustomChangeException { 
     JdbcConnection databaseConnection = (JdbcConnection) database.getConnection(); 
     try { 
      Set<InputStream> files = resourceAccessor.getResourcesAsStream(file); 
      if(files != null){ 
       for (InputStream inputStream : files) { 
        BufferedReader in = new BufferedReader(
          new InputStreamReader(inputStream)); 
        String str; 
        String sql; 
        StringBuilder sqlBuilder = new StringBuilder(""); 
        while ((str = in.readLine()) != null) { 
         sqlBuilder.append(str).append(" "); 
        } 
        in.close(); 
        sql = sqlBuilder.toString().trim(); 
        if(StringUtils.isEmpty(sql)){ 
         return; 
        } 
        Statement statement = databaseConnection.createStatement(); 
        statement.execute(sql); 
        statement.close(); 
       } 
      } 
     } catch (FileNotFoundException e) { 
      logger.error(e.getMessage(), e); 
     } catch (Exception e) { 
      throw new CustomChangeException(e); 
     } 
    } 

    public String getFile() { 
     return file; 
    } 

    public void setFile(String file) { 
     this.file = file; 
    } 

    @Override 
    public void setFileOpener(ResourceAccessor resourceAccessor) { 
     this.resourceAccessor = resourceAccessor; 
    } 
} 

我写的测试:

package com.mycompany.openapi.cms.core.support.liquibase; 

import com.google.common.collect.Sets; 
import liquibase.database.Database; 
import liquibase.database.jvm.JdbcConnection; 
import liquibase.resource.ResourceAccessor; 
import org.junit.Before; 
import org.junit.BeforeClass; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.InjectMocks; 
import org.mockito.Mock; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import java.io.ByteArrayInputStream; 
import java.io.InputStream; 
import java.nio.charset.StandardCharsets; 
import java.sql.Statement; 

import static org.mockito.Matchers.anyString; 
import static org.mockito.Mockito.verify; 
import static org.powermock.api.mockito.PowerMockito.*; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({LoggerFactory.class}) 
public class TestApplySqlFileIfExistsChange { 

    @InjectMocks 
    ApplySqlFileIfExistsChange applySqlFileIfExistsChange; 

    @Mock 
    private ResourceAccessor resourceAccessor; 

    @Mock 
    private JdbcConnection jdbcConnection; 

    @Mock 
    private Database database; 

    @Mock 
    Statement statement; 

    @BeforeClass 
    public static void setUpClass() { 
     mockStatic(LoggerFactory.class); 
     when(LoggerFactory.getLogger(ApplySqlFileIfExistsChange.class)).thenReturn(mock(Logger.class)); 
    } 

    @Before 
    public void setUp() throws Exception { 
     when(database.getConnection()).thenReturn(jdbcConnection); 

     InputStream inp1, inp2; 
     inp1 = new ByteArrayInputStream("FirstTestQuery".getBytes(StandardCharsets.UTF_8)); 
     inp2 = new ByteArrayInputStream("SecondTestQuery".getBytes(StandardCharsets.UTF_8)); 

     when(resourceAccessor.getResourcesAsStream(anyString())).thenReturn(Sets.newHashSet(inp1, inp2)); 
     when(jdbcConnection.createStatement()).thenReturn(statement); 
    } 

    @Test 
    public void execute() throws Exception { 
     applySqlFileIfExistsChange.execute(database); 
     verify(statement).execute("FirstTestQuery"); 
     verify(statement).execute("SecondTestQuery"); 
    } 

} 

问题是,以上测试在我的IDE通过,但是当我在仓库中推送TeamCity构建失败时,我的测试。我无法理解为什么,因为代码在两个地方都是一样的。以下是TeamCity中的堆栈跟踪:

java.lang.IllegalStateException: Failed to transform class with name org.slf4j.LoggerFactory. Reason: java.io.IOException: invalid constant type: 15 
    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:267) 
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:180) 
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:348) 
    at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114) 
    at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125) 
    at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49) 
    at sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:439) 
    at sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:420) 
    at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724) 
    at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531) 
    at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355) 
    at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286) 
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120) 
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) 
    at java.lang.Class.createAnnotationData(Class.java:3521) 
    at java.lang.Class.annotationData(Class.java:3510) 
    at java.lang.Class.getAnnotation(Class.java:3415) 
    at org.junit.internal.MethodSorter.getDeclaredMethods(MethodSorter.java:52) 
    at org.junit.internal.runners.TestClass.getAnnotatedMethods(TestClass.java:45) 
    at org.junit.internal.runners.MethodValidator.validateTestMethods(MethodValidator.java:71) 
    at org.junit.internal.runners.MethodValidator.validateStaticMethods(MethodValidator.j 

对于我的问题中的这样一些代码,我表示歉意。

+0

获取最新的源代码/依赖项,相同版本的测试工具? – lordkain

+0

是的,我们使用maven和pom.xml完全相同。 –

+0

看起来像一个重复:http://stackoverflow.com/questions/32854688/powermock-java-lang-illegalstateexception-failed-to-transform-class –

回答

1

您可能有冲突的Powermock/Mockito版本。 检查你的本地maven回购版本,并在你的pom中删除旧版本 和/或更新包含它的其他依赖项。

检查项目与根:

mvn dependency:tree -Dverbose -Dincludes=NAME_OF_DEPENDENCY 
1

你必须依赖库在TeamCity的回购VS本地回购冲突。

确认TC版本使用的是当地正在使用的完全相同版本的Powermock。

可能有一个旧版本正在被包含在内。

mvn dependency:tree -Dverbose

这将列出所有的解析依赖关系。看看是否有不同版本的Powermock。然后,您可以通过使用pom.xml中的exclude/exclusions标记来阻止它们被拉入。

+0

我已经提到过它,这是我第一次想到pom.xml,但它们是一样的。 –

+0

传递性是关键字。可能有另一个依赖关系将其拉入,然后TC以不同的方式加载类路径,因此使用不同的版本。 – UserF40

+0

可能你是对的。我会尽力做到这一点。 –