如何使用Mockito和TestNg测试枚举中的默认值

时间:2018-12-04 05:08:48

标签: java unit-testing enums mockito testng

我有一个像这样的第三方枚举类:

package se.api;
public enum InvestigationResultStatus {
  PENDING("PendingResult.rr"),
  NEW("NewResult.rr"),
  MODIFIED("ModifiedResult.rr"),
  FINAL("FinalResult.rr"),
  PRELIMINARY("PreliminaryResult.rr"),
  ADDITIONAL("AdditionalResult.rr"),
  REJECTED("RejectedResult.rr"),
  COMPLETE("Path.Results.InvestigationInformation.Complete"),
  UNDEFINED("");

  private final String languageKey;

  private InvestigationResultStatus(String languageKey) {
    this.languageKey = languageKey;
  }

  public String getLanguageKey() {
    return this.languageKey;
  }
}

在我的代码中,我为此类创建枚举

package se.dto;
public enum InvestigationResultStatus
{
   PENDING,
   NEW,
   MODIFIED,
   FINAL,
   PRELIMINARY,
   ADDITIONAL,
   REJECTED,
   UNDEFINED
}

将这些api枚举映射到我创建的枚举映射器的枚举:

package se.mapper;

import se.dto.InvestigationResultStatus;

public class InvestigationResultStatusMapper
{
  public InvestigationResultStatus mapOmResultStatusToNovaResultStatus(final se.api.InvestigationResultStatus investigationResultStatus){
    switch (investigationResultStatus){
      case PENDING:
        return InvestigationResultStatus.PENDING;
      case NEW:
        return InvestigationResultStatus.NEW;
      case MODIFIED:
        return InvestigationResultStatus.MODIFIED;
      case FINAL:
        return InvestigationResultStatus.FINAL;
      case PRELIMINARY:
        return InvestigationResultStatus.PRELIMINARY;
      case ADDITIONAL:
        return InvestigationResultStatus.ADDITIONAL;
      case REJECTED:
        return InvestigationResultStatus.REJECTED;
      case UNDEFINED:
        return InvestigationResultStatus.UNDEFINED;
      default:
        throw new IllegalArgumentException("Unknown InvestigationResultStatus: " + investigationResultStatus);
    }
  }
}

现在,我想测试InvestigationResultStatusMapper类的默认案例路径并抛出IllegalArgumentException。我以多种方式进行搜索和尝试。但是大多数示例都是使用powermockito。但是我想将Mackito与testNg一起使用。如何进行测试。我尝试使用此方法

@Test(expectedExceptions = { IllegalArgumentException.class })
  public void testMapOmResultStatusToNovaResultStatus_whenHaveDefaultValue_thenThrowIllegalArgumentException()
  {
    se.api.InvestigationResultStatus investigationResultStatusNewEnum = mock(se.api.InvestigationResultStatus.class);
    Whitebox.setInternalState(investigationResultStatusNewEnum, "name", "DEFAULT");
    Whitebox.setInternalState(investigationResultStatusNewEnum, "ordinal", "DefaultResult.rr");

    se.api.InvestigationResultStatus investigationResultStatusCosmic = mock(se.api.InvestigationResultStatus.class);

    when(investigationResultStatusCosmic.values()).thenReturn(
        new se.api.InvestigationResultStatus[] { InvestigationResultStatus.PENDING, InvestigationResultStatus.NEW,
            se.api.InvestigationResultStatus.MODIFIED, InvestigationResultStatus.FINAL, InvestigationResultStatus.PRELIMINARY,
            se.api.InvestigationResultStatus.ADDITIONAL, InvestigationResultStatus.REJECTED,
            se.api.InvestigationResultStatus.COMPLETE, InvestigationResultStatus.UNDEFINED, investigationResultStatusNewEnum });

    investigationResultStatusMapper.mapOmResultStatusToNovaResultStatus(investigationResultStatusNewEnum);
  }

3 个答案:

答案 0 :(得分:1)

您可以直接创建一个实例以避免模拟。

@Test(expectedExceptions = { IllegalArgumentException.class })
public void testMapOmResultStatusToNovaResultStatus_whenHaveDefaultValue_thenThrowIllegalArgumentException()
{

  InvestigationResultStatus investigation = new InvestigationResultStatus();
  investigation.mapOmResultStatusToNovaResultStatus(-10000);
   ....

}

答案 1 :(得分:1)

在这种情况下,我无法使用模拟程序来模拟enum(final)类

 @BeforeClass
  public void setUp()
  {
    investigationResultStatusMapper = new InvestigationResultStatusMapper();
    investigationResultStatusNewEnum = PowerMockito.mock(InvestigationResultStatus.class);


    Whitebox.setInternalState(investigationResultStatusNewEnum, "name", "TEST");
    Whitebox.setInternalState(investigationResultStatusNewEnum, "ordinal", 9);

    InvestigationResultStatus[] investigationResultStatuses = Arrays
        .copyOf(InvestigationResultStatus.values(), InvestigationResultStatus.values().length + 1);
    investigationResultStatuses[investigationResultStatuses.length - 1] = investigationResultStatusNewEnum;

    PowerMockito.mockStatic(InvestigationResultStatus.class);

    PowerMockito.when(InvestigationResultStatus.values()).thenReturn(
        investigationResultStatuses);
  }

  /**
   * Test Method for {@link InvestigationResultStatusMapper#mapOmResultStatusToNovaResultStatus(InvestigationResultStatus)}
   * extend the InvestigationResultStatus enum for DEFAULT throw {@link IllegalArgumentException})
   */
  @Test(expectedExceptions = {
      IllegalArgumentException.class }, expectedExceptionsMessageRegExp = "Unknown InvestigationResultStatus: TEST")
  public void testMapOmResultStatusToNovaResultStatus_whenHaveDefaultValue_thenThrowIllegalArgumentException()
  {
    investigationResultStatusMapper.mapOmResultStatusToNovaResultStatus(investigationResultStatusNewEnum);
  }

答案 2 :(得分:0)

方法错误。首先,第三方枚举具有 9 条目,但是您自己的枚举仅具有 8 。因此,当您的映射代码收到COMPLETE时,它将抛出该异常!但是,如果您自己的枚举有9个条目,而您只是将它们映射为1-1 ...首先在这里使用您自己的枚举有什么意义? (可能有充分的理由拥有它,但目前它并没有增加太多价值)。

除此问题外,您应该执行完全不同的操作:

您将这些映射放入了Map对象。然后编写一个单元测试,该测试使用InvestigationResultStatus.values()获取具有所有 valid InvestigationResultStatus常量的数组。您确保您的映射知道如何映射所有这些有效常量(例如,通过检查您是否获得了非null返回值)。此外,您可能需要对每个第三方常数进行一次测试,以检查预期结果。

这里的关键点是:不幸的是,枚举可能会随着时间而改变。因此,您绝对想知道何时将其他常量添加到第三个枚举中。

换句话说:分别是Java语言,编译器确保该第三方枚举不会有“无效”实例。当您拥有InvestigationResultStatus someEnumValue时,将100%清楚:someValue为null,或者它是该枚举中的常量之一。这里什么都没有!因此:无需期望,检查或处理“无效”值。