2011-09-15 13 views
10

統合テスト(ロードコンテキスト)とユニットテストを一緒に実行しています。私のコードは、springを使用してアスペクトをコンパイルする時間を行います。ユニットテスト実行中の特定の側面を無効にする

私の問題は、私の宣言されたアドバイスが私のユニットテストのいくつかの間に実行されることです。これは単体テストの概念を打ち消します。そのため私はそれらを無効にしたいのです。

Pointcut宣言、私が呼び出せるメソッド、Springの設定、またはこれらのアドバイスをすべて無効にするmavenコマンドが* UnitTest.javaのようなものがありますか?

ありがとうございました。


例:

I持って以下のユニットテスト:

@RunWith(MockitoJUnitRunner.class) 
public class CompanyServiceImplTest { 
    @Test 
    public void createCampaignTest() throws Exception { 
     when(companyDaoMock.saveCompany(any(Campaign.class))).thenReturn(77L); 

     Long campaignId = companyService.createCampaign(campaignMock); 

     assertEquals(Long.valueOf(77L), Long.valueOf(campaignId)); 
    } 
} 

及び次のサービス方法

@Override 
@Transactional 
@EventJournal(type = EventType.CAMPAIGN_CREATE, owner = EventOwner.TERMINAL_USER) 
public Long createCampaign(Campaign campaign) { 
    return companyDao.saveCompany(campaign); 
} 

態様:

@Aspect 
public class EventJournalAspect { 

    @Autowired 
    private EventJournalService eventJournalService; 

    @Pointcut(value="execution(public * *(..))") 
    public void anyPublicMethod() {} 

    @Pointcut("within(com.terminal.service..*)") 
    private void inService() {} 

    @AfterReturning(pointcut = "anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)", returning = "id") 
    public void process(Object id, EventJournal eventJournal, AbstractDomainEntity entity) 
      throws Throwable { 
     if (eventJournal.type() != EventType.CAMPAIGN_PAYMENT || id != null) { 
      saveEvent(eventJournal, EventStatus.SUCCESS, entity, (Long) id); 
     } 
    } 

    @AfterThrowing(pointcut = "anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)", throwing="ex") 
    public void processException(EventJournal eventJournal, AbstractDomainEntity entity, Exception ex) throws Throwable { 
     saveEvent(eventJournal, EventStatus.FAILURE, entity, null); 
    } 

    private void saveEvent(EventJournal eventJournal, EventStatus status, AbstractDomainEntity entity, Long persistentId) { 
     EventType type = eventJournal.type(); 
     EventOwner owner = eventJournal.owner(); 
     eventJournalService.saveEvent(type, owner, EventStatus.SUCCESS, entity, persistentId); 
    } 

} 

テスト実行時 - eventJournalServiceがnullです。したがって、私は参照してくださいNullPointerException

答えて

0

私は推測することができます: 最初のことは、コンポーネントのスキャンなしで別のSpringのapplicationContext-test.xml、 を持つことです。 mavenでは、テスト用の織り瓶を除いた段階ランタイムを追加できます。

0

コンパイル時の織り込みは、あなたが持っているポイントカットによって識別されるターゲットメソッドをアドバイスします。私は個人的には、実行時にあなたのユニットにアドバイスがインライン化されたクラスが含まれているので、コンパイル時にユニットテストを行うのが良いと感じていますか?

私はアドバイスを含まなくてはならないと思ったのは、コンパイル時に2つの異なるコンパイルターゲットを持つことです。コンパイル時には、コンパイル時には、コンパイル時に、面を織り成すためのプロファイル。

3

答えは簡単です:if() pointcut expressionを使います。更新


(質問も更新された後):上記元々提供されたリンクは、しかし、それは価値がある何のために、十分な情報が含まれている必要があり、簡単な説明と簡単な例:

アンif() pointcutはstaticアスペクトメソッドで、booleanを返します。戻り値がtrueの場合、myPointcut() && if()のような結合されたポイントカットは、myPointcut()が一致する限り一致します。戻り値がfalseの場合、結合されたポイントカット全体が一致せず、ポイントカットに接続されているアドバイスが効果的に無効になります。

スタティックif()ポイントカットで何ができますか?

  • ユニットや統合テスト時にのみ真であるTestMode.ACTIVEのようないくつかのツールクラスの静的なブールメンバーを評価
  • をテスト中に設定されている環境変数を評価するだけであるJavaシステムプロパティを評価あなたは、c、あなたは手の込んだ(そしてトリッキー)何かをしたい場合は
  • と、より多くの事

をテスト中に設定し、パフォーマンスはそれほど重要ではありませんオートワイヤアスペクトメンバ変数がnullかどうかを動的に判断し、注入されたオブジェクトが実際に存在する場合にのみポイントカットをアクティブにします。ここでの唯一の問題は、静的メソッドからメンバ変数を決定する方法です。私はSpring AOPについては考えていませんが、AspectJでは、補助クラスAspectsがあり、いくつかのオーバーロードされたメソッドaspectOf(..)があります。

@Pointcut("if()") 
public static boolean isActive() { 
    return Aspects.aspectOf(PerformanceMonitorAspect.class).eventJournalService != null; 
} 

// ... 

@AfterReturning(pointcut = "isActive() && anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)", returning = "id") 
// ... 

@AfterThrowing(pointcut = "isActive() && anyPublicMethod() && inService() && @annotation(eventJournal) && args(entity,..)", throwing="ex") 
// ... 
+0

例を入力してください – gstackoverflow

+0

元の投稿に詳細を追加しました。 – gstackoverflow

+0

元のポスターではない質問にどのように詳細を追加できますか? – kriegaex

0

あなたは現在の実行は、JUnitフレームワークを使用して開始された場合は返すメソッドを書くことができます:あなたの態様はシングルトンとしてインスタンス化されると仮定すると、あなたはこのような何かを行うことができます。

このメソッドは、Thread.currentThread()。getStackTrace()でスタックトレースをチェックし、MockitoJUnitRunnerの存在を検索できます。

私はこのソリューションをSpringJUnit4ClassRunnerでテストしましたが、私はMockitoJUnitRunnerで動作すると思います。あなたのプロジェクトに存在するクラスで

private static boolean TEST_ENVIRONMENT = false; 

(ないあなたのテストで)を、代わりに使用するスタックトレースの制御方法で値を確認します

また、あなたは次のように静的なブールフィールドを持っていることができます。

テストを実行するときに、@ BeeClassアノテーションを使用してTEST_ENVIRONMENT = trueを設定できます。

このソリューションでは、コードがテストから実行されているかどうかを知ることができます。

関連する問題