Junit Interface Powermock



编辑:用较短的方式改写问题。谢谢你指出这一点!:(

我需要编写JUnit测试,在那里我必须模拟几个没有setter/getter的私有方法和字段。我尝试了两种方法来实现它,分别是Mockito和PowerMock。问题是,有可能把这两者结合起来吗?首次尝试使用私有字段测试方法:

...
@Mock private XMLConfiguration config;
@InjectMocks AAIGroupController groupi;
@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}
...
    given(config.configurationsAt(anyString())).willReturn(ldapGroups);
...

PowerMock第二次尝试测试私有方法:

...
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来嘲笑私人领域。

另一个问题是:我必须为接口编写JUnit测试。这不重要吗,因为实现接口的类已经过测试了。如果没有,有什么好的做法呢?

提前感谢!

老问题,可以完全跳过。我把它放在这里只是为了理解已经给出的答案

我必须为接口编写JUnit测试,实现已经完成。但我有点困惑如何正确地为他们编写测试。我已经开始实施了,但现在我被卡住了。首先,我不确定我是否正确测试了接口,然后出现了嘲笑私有字段的问题。到目前为止,我已经编写了两个不同的测试类来进行测试。两个测试类现在都在"工作",但我想将它们合并到InterfaceAAIGroupControllerTest Class中,但不知道如何在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);
    }
}

我现在的问题是,我能像以前那样测试接口吗?这似乎不是一个好的解决方案。参数化似乎没有必要,因为永远只有一个实现,而我不知道如何使用两个Runner。。另一件事是,我如何使用上一个例子中的测试代码,在PowerMock测试类中模拟私有字段"config"?我不知道如何正确地模拟私有字段,并在从中调用方法时改变它的行为

提前感谢您的每一条建议!

阅读本文时会想到三个想法:

  • 你真的需要发布那么多代码吗?你真的希望我们能全部阅读吗?你的问题很含糊,很难理解。考虑一次问一个问题
  • 你不测试接口。一个接口没有任何代码,有什么可以测试的
  • 如果您使用PowerMock进行嘲讽,请不要在同一测试中也使用Mockito。根据您的要求使用其中一个

要设置专用字段,请提供一个setter(可能在默认范围内(或使用反射(如ReflectionTestUtils(进行设置。

相关内容

  • 没有找到相关文章

最新更新