文書の過去の版を表示しています。


Integration with TestNG

PowermockをTestNGと一緒に使う為に必要な設定をメモとして残しておく。
基本的に、testプロジェクトはMavenプロジェクトとして作成することを前提している。

Mavenプロジェクトのproperties設定を以下に示す。

keyvaluecomment
project.build.sourceEncodingUTF-8
java.version1.8
powermock.version2.0.9

Mavenプロジェクトのplugin設定を以下に示す。

  	<plugin>
  		<groupId>ora.apache.maven.plugins</groupId>
  		<artifactId>maven-compiler-plugin</artifactId>
  		<version>3.8.1</version>
  		<configuration>
  	  		<source>${java.version}</source>
  			<target>${java.version}</target>
  		</configuration>
  	</plugin>

TestNGと一緒に使う場合は、下記モジュールの導入が必要だ。
必要モジュールを下記に示す。

groupIdartifactIdversionscope
org.powermockpowermock-module-testng${powermock.version}test
org.powermockpowermock-api-mockito${powermock.version}test

その他、必要モジュールを導入するが、基本的に入れるモジュールを以下に示す。

groupIdartifactIdversionscope
org.dbunitdbunit2.5.4
org.apache.commonscommons-lang33.7
org.apache.poipoi3.17
org.apache.poipoi-ooxml3.17
commons-iocommons-io2.1
commons-beanutilscommons-beanutils1.9.3
com.google.injectguice4.2.2
ch.qos.logbacklogback-classic1.2.3test

Common Parent Test Class

Testクラスが共通で継承する親クラスについて、サンプルとして残しておく。

@Listeners({CustomTestMethodListener.class})
@MockPolicy(Slf4jMockPolicy.class)
@PowerMockIgnore({"javax.management.*", "javax.security.auth.x500.X500Principal", "javax.net.ssl.*",
	"oracle.jdbc.*", "javax.sql.*", "com.microsoft.sqlserver.*"})
public abstract class AbstractCustomTestCase extends PowerMockTestCase {
    /** DBUnitのテスター */
    protected IDatabaseTester databaseTester;
 
    //overwrite createWorkbook for Xlsx data set
    //DBUnitでXlsxをITableとして使えるよう、override
    protected final XlsDataSetWriter xlsxWriter = new XlsDataSetWriter() {
        /* (non-Javadoc)
	 * @see org.dbunit.dataset.excel.XlsDataSetWriter#createWorkbook()
	 */
	@Override
	protected Workbook createWorkbook() {
	    return new XSSFWorkbook();
	}
    };
 
    //***** public method *****
    //***** protected method *****
 
    @BeforeClass
    protected void setUp() throws Exception {
	setUpDbunitTester();
	prepareSpecific();
    }
 
    @AfterClass
    protected void tearDown() throws Exception {
	databaseTester.setTearDownOperation(DatabaseOperation.NONE);
	databaseTester.onTearDown();
	tearDownHook();
    }
 
    protected abstract void prepareSpecific() throws Exception;
 
    protected void tearDownHook() throws Exception {
	//nop
    }
 
    //***** private method *****
 
    // Creates a new JdbcDatabaseTester
    private void setUpDbunitTester() throws Exception {
	DataSource _ds = DataSourceLocator.getDataSource(DBConstants.NPDS);
	databaseTester = new DataSourceDatabaseTester(_ds);
 
	// ----------------------------------
	// Database config
	// ----------------------------------
	DatabaseConfig _config = databaseTester.getConnection().getConfig();
	_config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new OracleDataTypeFactory());
    }
 
}

@Listeners

Test実行中のあるフェーズで共通の処理を追加したい場合の為に、TestNGではListener1)というInterfaceを提供している。
通常テストを行う際、メソッド1個のみ実行することはない。
今なんのメソッドが実行されたかをコンソールで確認し易いために、IInvokeMethodListenerを実装しておくと便利だ。
サンプルのParent Classでは、CustomTestMethodListenerを指定しているが、コードを以下に示す。

public class CustomTestMethodListener implements IInvokedMethodListener {
 
    //***** injection field *****
    //***** constructor *****
    //***** public method *****
 
    /**
     * @see org.testng.IInvokedMethodListener#beforeInvocation(org.testng.IInvokedMethod, org.testng.ITestResult)
     */
    public void beforeInvocation(IInvokedMethod method, ITestResult testResult) {
	if (method.isTestMethod()) {
            System.out.println("on test method " +  method.getTestMethod().getMethodName() + " start");
	    //paramerters
	    System.out.println("parameters:" + ToStringBuilder.reflectionToString(testResult.getParameters(), ToStringStyle.SIMPLE_STYLE));
        }
    }
 
    /**
     * @see org.testng.IInvokedMethodListener#afterInvocation(org.testng.IInvokedMethod, org.testng.ITestResult)
     */
    public void afterInvocation(IInvokedMethod method, ITestResult testResult) {
        // nop
    }
 
}

@MockPolicy

Powermockをlog4j又はslf4jと一緒に使う場合、次のエラーが発生することがある。

log4j:ERROR A "org.apache.log4j.xml.DOMConfigurator" object is not assignable to a "org.apache.log4j.spi.Configurator" variable.
log4j:ERROR The class "org.apache.log4j.spi.Configurator" was loaded by
log4j:ERROR [org.powermock.core.classloader.MockClassLoader@14a55f2] whereas object of type
log4j:ERROR "org.apache.log4j.xml.DOMConfigurator" was loaded by [sun.misc.Launcher$AppClassLoader@92e78c].
log4j:ERROR Could not instantiate configurator [org.apache.log4j.xml.DOMConfigurator].

解決策はいくつか2)あるが、簡単なのは、MockPolicy annotationを利用してlog実装体を指定する方法だ。
Log4jのみ利用する場合は、@MockPolicy(Log4jMockPolicy.class)
Slf4jとLog4jを併用する場合は、@MockPolicy(Slf4jMockPolicy.class)を指定する。

@PowerMockIgnore

TestNGとPowerMockを同時に使うと、TestNGのClassLoaderによりloadingされたクラスが、PowerMockerのClassLoaderにloadingされエラーになることがある。
それを回避させるために、用意されているのが@PowerMockIgnore annotationになる。

サンプルのParentクラスで指定した設定の意味を次に示す。

package or class目的
javax.management.*DBUnitと統合
javax.net.ssl.*DBUnitと統合
javax.security.auth.x500.X500PrincipalDBUnitと統合
oracle.jdbc.*Oracle接続
javax.sql.*SQL Server接続
com.microsoft.sqlserver.*SQL Server接続

QR Code
QR Code study:java:powermock:integation (generated for current page)