如何使用额外的jmockit参数测试参数化单元测试用例?

时间:2015-11-30 07:09:02

标签: java junit

我有这个单元测试代码用于模拟某些东西:

import org.junit.Assert;
import org.junit.Test;
import mockit.*;
import org.junit.runner.RunWith;
import com.googlecode.zohhak.api.TestWith;
import com.googlecode.zohhak.api.runners.ZohhakRunner;


@RunWith(ZohhakRunner.class)
public class PersonTest{
    @Test
    public void testGetName(@Capturing final Person p) {
        // I need P object for mocking;
        Assert.assertTrue(true);
    }

    @TestWith({
            "1, 1",
            "2, 2"
    })
    public void test_is_euqal(int input, int expected,  @Capturing final Person p){
        // ... some code here ...
        // I need P Object for mocking but don't want to use it as parametrized 
        Assert.assertEquals(Integer.valueOf(expected), Integer.valueOf(input));
    }
}

第一个测试用例(testGetName)没问题,但第二次测试抛出ArrayIndexOutOfBoundsException异常,因为我在参数中使用了@capturing。有没有办法向测试用例发送一个参数,并且在没有抛出任何parametrized异常的情况下不ArrayIndexOutOfBoundsException它?

3 个答案:

答案 0 :(得分:0)

简短回答:你做不到。

更长的答案:

事实上,你试图自动组合2种不同的跑步者,这些跑步者通常在junit中是不可能的。我能想到的最简单的解决方法是:

  • 在没有@Capturing注释
  • 的情况下手动在测试方法内创建模拟
  • 在字段上使用@Capturing而不是在参数上使用(我知道,它可能会变得混乱)
  • 上述两者的组合

答案 1 :(得分:0)

使用AssertJ的SoftAssertions,您可以在单个测试中模拟参数:

    @Tested
    private Foo foo;

    @Mocked
    private Baz baz;

    @Test
    public void givenFoo_WhenGetBar_ShouldBeExpected() throws Exception {

        List<Parameters> parametersList = asList(
                new Parameters(param1, expecte1),
                new Parameters(param2, expected2),
                new Parameters(param3, expeted3));

        // For each parameter set expectations and get actual
        // needs to be in for loop instead of forEach if exceptions are checked
        for (final Parameters parameters : parametersList) { 

            new Expectations() {{
                baz.get();
                result = parameters.param;
            }};

            parameters.actual = foo.getBar();
        }

        // This will give a test case name and assert on each item even if another item fails
        // the same functionality of parameterized tests but in a single Test
        assertSoftly(softly -> parametersList
                .forEach(parameters -> softly.assertThat(parameters.actual) // doesn't short circuit
                        .as(parameters.toString()) // test case name
                        .isEqualTo(parameters.expected)));

    }

  private class Parameters {
      Parameters(ParamType param, ExpectedType expected){
          this.param = param;
          this.expected = expected;
      }
      private final ParamType param;
      private final ExpectedType expected;
      private ActualType actual;

      @Override
      public String toString(){
          return String.format("param: %s expected: %s",param,expected);
      }
  }

答案 2 :(得分:-3)

试试这个

public void test_is_euqal(int input, int expected,  Person p=null)