1

編集済み:質問をより短い方法で書き直しました。これを指摘してくれてありがとう!:)

セッター/ゲッターなしでいくつかのプライベートメソッドとフィールドをモックする必要がある JUnit テストを作成する必要があります。これを達成するために、Mockito と PowerMock の 2 つの方法を試しました。問題は、この 2 つを組み合わせることができるかどうかです。プライベート フィールドを使用してメソッドをテストする最初の試み:

...
@Mock private XMLConfiguration config;
@InjectMocks AAIGroupController groupi;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}
...

    given(config.configurationsAt(anyString())).willReturn(ldapGroups);
...

PowerMock を使用してプライベート メソッドをテストする 2 回目の試行:

...
AAIGroupController groupC = PowerMockito.spy(new AAIGroupController());
...
when(groupC, method(AAIGroupController.class, "getLdapGroupNodeFromGroupConfigFile", ELUser.class))
        .withArguments(any(ELUser.class))
        .thenReturn(sn);
assertTrue(iaigroupi.isPosixAccount(new ELUserAAI(null, true, false)));
...

それらを組み合わせる方法はありますか、または PowerMock のみを使用する必要がありますか? PowerMock でプライベート フィールドをモックするのに問題があります。

もう 1 つの質問は、インターフェース用の JUnit テストを書かなければならないということです。インターフェイスを実装するクラスは既にテストされているため、これはナンセンスですか。そうでない場合、そのための良い習慣は何ですか?

前もって感謝します!

古い質問は、完全にスキップできます。すでに与えられた答えを理解するためにここに置いておきます。

実装がすでに完了しているインターフェイスの JUnit テストを作成する必要があります。しかし、それらのテストを適切に作成する方法について少し混乱しています。実装を開始しましたが、現在行き詰まっています。まず、インターフェイスを正しくテストしたかどうかわからないので、プライベート フィールドのモックに問題があります。これまでのところ、試してみるために 2 つの異なるテストクラスを作成しました。両方のテストクラスは現在「機能」していますが、それらを InterfaceAAIGroupControllerTest クラスにマージしたいと考えていますが、PowerMock 内で Mockito を使用する方法がわかりません。インターフェースには、私が使用します

groupi = PowerMockito.spy(new AAIGroupController());

そして、私が使用する他のテストのために

@Mock private XMLConfiguration config;
@InjectMocks AAIGroupController groupi;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

コードの場合:

インターフェース:

public interface IAAIGroupController {

/**
* Appends a new group entry
*/
public void appendGroup();

/**
 * checks if a given account is a possix account
 * 
 * @param elUser the user object to check
 * @return true if is posix, otherwise false
 * @throws ConfigurationException
 */
public boolean isPosixAccount(ELUser elUser)

...

実装

@Override
public void appendGroup() {
    try {
        config.addProperty("ldapGroup(-1)",

        List<SubnodeConfiguration> ldapGroups = config.configurationsAt("ldapGroup");
        SubnodeConfiguration sn = ldapGroups.get(ldapGroups.size()-1);
        try {
            sn.addProperty("script(-1)", null);
            // TODO Configuration 
        } catch (Exception e) {
            sn.addProperty("script(-1)", "default.sh");
        }

        config.save();
    } catch (ConfigurationException ex) {
        LOGGER.log(Level.SEVERE, ex.getMessage());
    }
}

@Override
public boolean isPosixAccount(final ELUser elUser) throws ConfigurationException {
    SubnodeConfiguration ldapGroup = getLdapGroupNodeFromGroupConfigFile(elUser);
    String posix = ldapGroup.getString("[@posix]");
    if (posix == null || posix.isEmpty() || posix.equalsIgnoreCase("true")) {
        return true;
    } else if (posix.equalsIgnoreCase("false")) {
        return false;
    } else {
        throw new ConfigurationException("posix attribute is not set properly!");
    }
}

インターフェースのテスト コードは、今のところ例外を適切に処理していませんが、機能すると修正されます。実装でプライベート メソッドを呼び出す必要があるため、PowerMock を使用しています。この方法でインターフェイスをうまくテストできるかどうかはわかりません。

@RunWith(PowerMockRunner.class)
@PrepareForTest(AAIGroupController.class)
public class InterfaceAAIGroupControllerTest {

    public IAAIGroupController iaigroupi;
    public AAIGroupController groupi;
    public XMLConfiguration config;


    @Before
    public void setUp() {
        groupi = PowerMockito.spy(new AAIGroupController());
        config = Whitebox.getInternalState(groupi, "config");
        iaigroupi = groupi;
    }

    @Test
    public void isPosixAccount_True() {
        try {
        SubnodeConfiguration sn = mock(SubnodeConfiguration.class);
        when(iaigroupi, method(AAIGroupController.class, "getLdapGroupNodeFromGroupConfigFile", ELUser.class))
        .withArguments(any(ELUser.class))
        .thenReturn(sn);

            assertTrue(iaigroupi.isPosixAccount(new ELUserAAI(null, true, false)));
        } catch (ConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

実装のテスト コード。ここでは、Mockito を使用して、コードで使用されているが、コンストラクターまたはメソッドによって設定されていないプライベート フィールドをモックします。

@RunWith(MockitoJUnitRunner.class)
public class AAIGroupControllerTest {

    @Mock private XMLConfiguration config;
    @InjectMocks AAIGroupController groupi;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void appendGroupTest() {
        List<SubnodeConfiguration> ldapGroups = mock(List.class);
        SubnodeConfiguration sn = mock(SubnodeConfiguration.class);
        given(config.configurationsAt(anyString())).willReturn(ldapGroups);
        given(ldapGroups.size()).willReturn(11);
        given(ldapGroups.get(ldapGroups.size()-1)).willReturn(sn);
        groupi.appendGroup();
        verify(sn).addProperty("script(-1)", null);
    }

}

私の今の問題は、私のようにインターフェイスをテストできるかということです。良い解決策ではないようです。実装は常に 1 つしかなく、2 つの Runner を使用する方法がわからないため、パラメータ化は不要のようです。もう 1 つは、プライベート フィールド「config」をモックする最後の例のテストコードをどのように使用できるかということです。 PowerMock テストクラス内? プライベート フィールドを正しくモックし、そこからメソッドが呼び出されたときの動作を変更する方法がわかりません。

すべてのヒントを事前にありがとう!

4

1 に答える 1