2017-08-11 9 views
0

WCMUsePOJOを継承する次のクラスのユニットテストケースを記述しています。今、このクラスは、以下に示すgetSlingScriptHelperメソッドを使用しています。ユニットテストWCMUsePOJOクラス

public class ConstantsServiceProvider extends WCMUsePojo { 
private static final Logger logger = LoggerFactory.getLogger(ConstantsServiceProvider.class); 

private String var1; 

@Override 
public void activate() throws Exception { 
    ConstantsService constantsService = getSlingScriptHelper().getService(ConstantsService.class); 
    if(constantsService != null) { 
     var1 = constantsService.getVar1(); 
    } 
} 

public string getVar1() { return var1; } 

} 

質問はどうやってgetSlingScriptHelperメソッドを模倣するのですか?以下は私のユニットテストコードです。

パブリッククラスConstantsServiceProviderTest {

@Rule 
public final SlingContext context = new SlingContext(ResourceResolverType.JCR_MOCK); 

@Mock 
public SlingScriptHelper scriptHelper; 

public ConstantsServiceProviderTest() throws Exception { 

} 

@Before 
public void setUp() throws Exception { 
    ConstantsService service = new ConstantsService(); 
    scriptHelper = context.slingScriptHelper(); 
    provider = new ConstantsServiceProvider(); 

    provider.activate(); 
} 

@Test 
public void testGetvar1() throws Exception { 
    String testvar1 = ""; 
    String var1 = provider.getVar1(); 
    assertEquals(testvar1, var1); 
} 
} 

答えて

2

あなたはユニットテスト、それにしたい場合は、ConstantsServiceProvider.classのモックを作成することはできません。代わりに、内部オブジェクトのモックを作成する必要があります。だから、:

  1. getSlingScriptHelper().getService(.)メソッドによって返されnew
  2. モックオブジェクトとConstantsServiceProviderの実際のインスタンスを作成します。通常、依存関係は、Springのようないくつかのコンテナによってクラスに提供(注入)されるか、setterを使用して他のクラスのアプリケーションから提供されます。どちらの場合でも、モックの作成は簡単です。
  3. 現在の実装でこれが許可されていない場合は、リファクタリングを検討してください。
  4. 何も返さないvoid activate()メソッドをテストしています。したがって、constantsService.getVar1()メソッドを呼び出して確認する必要があります。

私は強くあなたがここで可能な解決策の一つをVogella unit-testing tutorial

2

を研究するためにアドバイス。 主なアイデアは、あなたのクラスの実際のオブジェクトを持つことですが、を返すためにオーバーライドされたgetSlingScriptHelper()が返されます。

私はConstantsServiceも嘲笑しましたが、必要でないかもしれませんが、あなたのコードは分かりません。

public class ConstantsServiceProviderTest { 
    @Mock 
    public SlingScriptHelper scriptHelper; 

    @Test 
    public void getVar1ReturnsActivatedValue() throws Exception { 
     // setup 
     final String expectedResult = "some value"; 

     // Have a mocked ConstantsService, but if possible have a real instance. 
     final ConstantsService mockedConstantsService = 
      Mockito.mock(ConstantsService.class); 
     Mockito.when(
      mockedConstantsService.getVar1()) 
       .thenReturn(expectedResult); 

     Mockito.when(
      scriptHelper.getService(ConstantsService.class)) 
       .thenReturn(mockedConstantsService); 

     // Have a real instance of your class under testing but with overridden getSlingScriptHelper() 
     final ConstantsServiceProvider providerWithMockedHelper = 
      new ConstantsServiceProvider() { 
       @Override 
       SlingScriptHelper getSlingScriptHelper() { 
        return scriptHelper; 
       } 
      }; 

     // when 
     String actualResult = providerWithMockedHelper.getVar1(); 

     // then 
     assertEquals(expectedResult, actualResult); 
    } 
} 
+0

ありがとうございました。私はslingscripthelperを働かせることができました。私の方法はあなたの解決策に非常によく似ています。私はBindingsクラスも模擬しなければならなかった。 '//スリングスクリプトのバインディングを設定します。 ' Bindings bindings = mock(Bindings.class); ' 'when(bindings.get(" sling "))thenReturn(context.slingScriptHelper());' これを追加してください'provider.init(bindings)'メソッドを呼び出します。 ** init()**の内部で呼び出されるので、これは最終的にactivateメソッドを実行します。 – romie99

+0

これが正しいと感じる場合は、ソリューションに追加することができます。私はあなたの答えを正しいものとしてマークします。 :) – romie99

+0

はい、あなたの実際のプロジェクトでは、正しいバージョンが必要です。ここでStackoverflow上の目的は、主なアイデアを提供するために、著者のブロックを解除するためにいくつかの詳細が見逃されることがあります。あなたの場合、 'init()'と 'Binding'についてはわかりませんでした。元の投稿では見つからなかったので、あなたの質問と一貫性を持たせるためにそのまま残しておきます。 –

1

それが宣言されたサービスの依存性注入を模倣するように、あなたは*モック「に持っている」必要がある唯一のものは、SlingScriptHelperインスタンス自体です。他

すべて(例えばバインディングインスタンス)は、例えば、具体的な実装することができます:ここ

import org.apache.sling.api.scripting.SlingBindings; 
import org.apache.sling.api.scripting.SlingScriptHelper; 
import org.junit.Test; 

import javax.script.Bindings; 
import javax.script.SimpleBindings; 

import static org.hamcrest.CoreMatchers.equalTo; 
import static org.hamcrest.CoreMatchers.is; 
import static org.hamcrest.MatcherAssert.assertThat; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.when; 

public class ConstantsServiceProviderTest { 

    private SlingScriptHelper mockSling = mock(SlingScriptHelper.class); 
    private ConstantsServiceProvider constantsServiceProvider = new ConstantsServiceProvider(); 
    private Bindings bindings = new SimpleBindings(); 

    @Test 
    public void testFoo() throws Exception { 
     //Arrange 
     final String expected = "Hello world"; 
     final ConstantsService testConstantsService = new TestConstantsService(expected); 
     when(mockSling.getService(ConstantsService.class)).thenReturn(testConstantsService); 
     bindings.put(SlingBindings.SLING, mockSling); 

     //Act 
     constantsServiceProvider.init(bindings); 

     //Assert 
     final String actual = constantsServiceProvider.getVar1(); 
     assertThat(actual, is(equalTo(expected))); 
    } 

    class TestConstantsService extends ConstantsService { 
     String var1 = ""; 

     TestConstantsService(String var1) { 
      this.var1 = var1; 
     } 

     @Override 
     String getVar1() { 
      return var1; 
     } 
    } 

} 

エントリポイント、あなたは上記の言ったように、このようWCMUsePojoスーパークラス(のinit()メソッドを介してですメソッドはUse.classインターフェイスの実装です。このテスト構造は、WCMUsePojoを直接使用しない場合でも、そのインターフェイスを介してテストするためにも機能します)。

*これは任意のタイプのテストダブルであり、必ずしもモック。

関連する問題