7

PowerMock と PowerRule を Mockito を使用して JUnit に統合しました。

ここに私の依存関係があります:

<dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.0.GA</version>
      </dependency>
<dependency>
        <groupId>asm</groupId>
        <artifactId>asm</artifactId>
        <version>3.3.1</version>
</dependency>

 <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
 </dependency>
 <dependency>
        <groupId>org.powermoc</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.4.12</version>
    <scope>test</scope>
    </dependency>
 <dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.4.12</version>
    <scope>test</scope>
 </dependency>
 <dependency>
       <groupId>org.powermock</groupId>
       <artifactId>powermock-module-junit4-rule</artifactId>
       <version>1.4.12</version>
       <scope>test</scope>
 </dependency>
 <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-classloading-objenesis</artifactId>
        <version>1.4.12</version>
        <scope>test</scope>
 </dependency>

私のテストクラスは次のとおりです。

public class TestClass extends AbstractShiroTest{
    @Rule
    public PowerMockRule rule = new PowerMockRule();
    @Autowired
    SomeService someService;
    @Before

    public void setUp(){
    Map<String, Object> newMap = new HashMap<String, Object>();
    newMap.put("userTimeZone", "Asia/Calcutta");
    Subject subjectUnderTest = mock(Subject.class);
             when(subjectUnderTest.getPrincipal()).thenReturn(LMPTestConstants.USER_NAME);
    Session session = mock(Session.class);
    when(session.getAttribute(LMPCoreConstants.USER_DETAILS_MAP)).thenReturn(newMap);
    when(subjectUnderTest.getSession(false)).thenReturn(session);
    setSubject(subjectUnderTest);
    PowerMockito.mockStatic(CasSessionUtil.class);
    when(CasSessionUtil.getCarrierId()).thenReturn(1L);
}

  @Test

public void myTestMethod()  {
someService.doSomething();
 }
}

doSomethingモックする必要がある静的メソッドを呼び出しています。テストケースを実行すると、javassist.NotFoundException: $Proxy88.

完全なスタック トレース:

java.lang.RuntimeException: javassist.NotFoundException: $Proxy88 at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:187) at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:147) org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67) で java.lang.ClassLoader.loadClass(ClassLoader.java:252) で java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) でorg.powermock の java.lang.Class.forName(Class.java:247) の java.lang.Class.forName0(ネイティブ メソッド)。 api.support.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:26) org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:243) org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) で org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) で org.powermock.classloading.DeepCloner.performClone(DeepCloner.java) で:128) org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) で org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) で org.powermock.classloading.DeepCloner.cloneFields(DeepCloner. java:248) org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) で org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) で org.powermock.classloading.DeepCloner.performClone(DeepCloner) で.java:128) の org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) の org.powermock.classloading.DeepCloner.org.powermock.classloading.DeepCloner.cloneFields(DeepCloner.java:248) の performClone(DeepCloner.java:128) org.powermock.classloading.DeepCloner.performClone(DeepCloner.java:128) の org.powermock.classloading.DeepCloner org.powermock.classloading の .clone(DeepCloner.java:82) .DeepCloner.clone(DeepCloner.java:69) org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat. java:72) org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) で org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) org org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) ) org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) で org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) で org.springframework. test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) org.junit.runners.ParentRunner.run(ParentRunner.java:236) org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) で org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) で org.eclipse .jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) org.eclipse.jdt.internal .junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner .RemoteTestRunner.main(RemoteTestRunner.java:197) 原因: javassist.NotFoundException: $Proxy88 at javassist.ClassPool.get(ClassPool.java:436) at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:180) ... 46 もっと見る

依存関係を変更すると

<dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-classloading-xstream</artifactId>
            <version>1.4.12</version>
            <scope>test</scope>
        </dependency>

その後、別の例外が発生します。https://stackoverflow.com/questions/12176049/suggest-work-around-for-com-thoughtworks-xstream-converters-conversionexceptionを参照してください(削除された SO の質問、10k が必要です)。

javassist バージョン 15 でも試してみましたが、同じ問題があります。

4

4 に答える 4

8

自分で解決策を見つけました:

以下の依存関係を使用します (Power Mock と Power Rule のみ)。

    <!-- Required for PowerMock -->
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito</artifactId>
        <version>1.4.12</version>
        <scope>test</scope>
    </dependency>
    <!-- Required for PowerMockRule -->
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4-rule-agent</artifactId>
        <version>1.4.12</version>
        <scope>test</scope>
    </dependency>

今、私は上記の例外のいずれも取得していません

于 2012-10-24T05:09:26.020 に答える
2

これ以上のコードサンプルがない場合、コードはテストでSpringを使用していることがわかります。したがって、このエラーの理由は、JDKプロキシ($Proxy88)を生成したように見えるSpringの使用に関連しているためだと思います。

そして、Powermockが機能する方法は、これらのクラスのバイトコードを変更するために新しいクラスローダーでJUnitテストを実行することです。残念ながら、バイトコードを変更できるのは、実際のファイルから、または少なくとも可能な場所からのみです。 javaはJVMにすでにロードされているバイトコードにアクセスできないため、クラスバイナリを読み取ります。(限られた方法でエージェントで可能かもしれません)。

JDKプロキシはディスク上に存在しないため、特定のPowermockクラスローダーに読み取ったりコピーしたりすることはできません。

作成しているテストは、Springコンテキストで実行されるため、単体テストではありません。最初に実際の単体テストを作成することをお勧めします。次に、モックを必要としない統合テストを行います。

また、統計の使用はテスト容易性の悪夢であるため、避ける必要があります。静的呼び出しをモックする必要がない方法で、実動コードを書き直す必要があります。

乾杯、

于 2012-08-30T08:07:18.533 に答える
0
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/test-servlet.xml")
public class ControlCenterManagerImplTest {

@Rule
public  PowerMockRule rule = new PowerMockRule();

//Powermock agent initialization not required and using maven dependency specified above by BHUVAN we can execute Power mock using spring.}
于 2013-03-21T07:34:55.537 に答える