自动装配的替代方法是在通过TestNG运行类时使用什么?

huangapple go评论78阅读模式
英文:

What is the alternative to autowiring while running a class through testNG?

问题

我正在验证ABCValidatorTest.java中的testValidateABC()方法。

ABCValidatorTest.java

public class ABCValidatorTest {

    @Test
    public void testValidateABC() {
        ABCValidator validator = new ABCValidator();
        List<String> input = Arrays.asList("0", "1234", "abcd");
        List<Boolean> expectedOutput = Arrays.asList(false, true, false);
        boolean output;

        for (int i = 0; i < input.size(); i++) {
            if (StringUtils.isNotEmpty(input.get(i))) {
                output = validator.validateABC(input.get(i));
            } else {
                output = false;
            }
            Assert.assertEquals((boolean) expectedOutput.get(i), output);

        }
    }

}

这里我创建了一个ABCValidator的对象,下面是它的类定义:

ABCValidator.java

public class ABCValidator {

    @Autowired(required = false)
    private ABCSearch abcRestClient;

    public boolean validateABC(String abc_code) {
        String response = abcRestClient.searchABCCodes(abc_code);
        boolean hasValidabc = true;
        if ((response.startsWith("null", 1)) || (response.equals("[]"))) {
            hasValidabc = false;
        }
        return hasValidabc;
    }
}

在这里,我使用@Autowired注入了ABCSearch以获取searchABCCodes()方法。

当我运行这段代码时,由于abcRestClient未初始化,我得到了一个NullPointerException。我如何在不更改ABCValidator.java中的任何内容的情况下修复这个问题?

英文:

I am validating the method testValidateABC() in ABCValidatorTest.java

ABCValidatorTest.java

public class ABCValidatorTest {

 @Test
    public void testValidateABC() {
        ABCValidator validator = new ABCValidator();
        List&lt;String&gt; input = Arrays.asList(&quot;0&quot;, &quot;1234&quot;, &quot;abcd&quot;);
        List&lt;Boolean&gt; expectedOutput = Arrays.asList(false, true, false);
        boolean output;

        for (int i = 0; i &lt; input.size(); i++) {
            if (StringUtils.isNotEmpty(input.get(i))) {
                output = validator.validateABC(input.get(i));
            } else {
                output = false;
            }
            Assert.assertEquals((boolean) expectedOutput.get(i), output);

        }
    }

}

Here I am creating an object of ABCValidator and below is its class:

ABCValidator.java

public class ABCValidator {

    @Autowired(required = false)
    private ABCSearch abcRestClient;

    public boolean validateABC(String abc_code) {
        String response = abcRestClient.searchABCCodes(abc_code);
        boolean hasValidabc = true;
        if ((response.startsWith(&quot;null&quot;, 1)) || (response.equals(&quot;[]&quot;))) {
            hasValidabc = false;
        }
        return hasValidabc;
    }
}

Here I have autowired ABCSearch to get the method searchABCCodes().

I am getting a NullPointerException when i run this since abcRestClient is not intitalized. How can I fix this without changing anything in ABCValidator.java?

答案1

得分: 1

清晰的解决方案是使用构造函数注入,而不是字段注入。(出于多种原因,包括可以防止几类错误,这是一个不错的想法。)

然后,您不需要任何特殊的Spring或反射支持,只需要一个普通的模拟对象:

@Test
public void testValidateABC() {
    ABCSearch mockRestClient = Mockito.mock(ABCSearch.class);
    ABCValidator validator = new ABCValidator(mockRestClient);
    List<String> input = Arrays.asList("0", "1234", "abcd");
    List<Boolean> expectedOutput = Arrays.asList(false, true, false);

    for (int i = 0; i < input.size(); i++) {
        when(mockRestClient.searchABCCodes(input.get(i))).thenReturn(/* 正确的布尔值 */);
        Assert.assertEquals((boolean) expectedOutput.get(i), validator.validateABC(input.get(i)));
    }
}

请注意,您在这里所做的是一个_参数化测试_;我对TestNG不是特别熟悉,但我预期它支持这种功能。我是 Spock 的粉丝(这是一个在JUnit之上运行的测试DSL),它可以让这种类型的测试非常清晰易读。

英文:

The clean answer is to use constructor injection instead of field injection. (This is a good idea for a number of reasons, including that it prevents several categories of bugs.)

Then you don't need any special Spring or reflection support, just a normal mock:

@Test
public void testValidateABC() {
    ABCSearch mockRestClient = Mockito.mock(ABCSearch.class);
    ABCValidator validator = new ABCValidator(mockRestClient);
    List&lt;String&gt; input = Arrays.asList(&quot;0&quot;, &quot;1234&quot;, &quot;abcd&quot;);
    List&lt;Boolean&gt; expectedOutput = Arrays.asList(false, true, false);

    for (int i = 0; i &lt; input.size(); i++) {
        when(mockRestClient.searchABCCodes(input.get(i)).thenReturn(/* the correct boolean */);
        Assert.assertEquals((boolean) expectedOutput.get(i), validator.validateABC(input.get(i)));
    }
}

Note that what you're doing here is called a parameterized test; I'm not especially familiar with TestNG but expect there is support for it. I am a fan of Spock (a test DSL that runs on top of JUnit) that makes this kind of test very clean.

答案2

得分: 0

@RunWith(MockitoRunner.class)
public class ABCValidatorTest {

    @Mock
    private ABCSearch search;

    @DataProvider(name = "dataSet")
    public static Object[][] createdataSet() {
        return new Object[][] { { "one", true }, { "three", true }, { "four", true }, { "five", true }, };
    }

    @Test(dataProvider = "dataSet")
    public void testValidateABC(String input, Boolean expectedResult) {
        ABCValidator validator = new ABCValidator();
        Whitebox.setInternalState(validator, "abcRestClient", search);
        output = validator.validateABC(input);
        Assert.assertEquals(expectedResult, output);
    }
}
英文:

If you want to write a unit test you can use Mocktio and parameterized test in Testng

@RunWith(MockitoRunner.class)
public class ABCValidatorTest {

    @Mock
    private ABCSearch search;

    @DataProvider(name = &quot;dataSet&quot;)
    public static Object[][] createdataSet() {
        return new Object[][] { { &quot;one&quot;, true }, { &quot;three&quot;, true }, { &quot;four&quot;, true }, { &quot;five&quot;, true }, };
    }

    @Test(dataProvider = &quot;dataSet&quot;)
    public void testValidateABC(String input, Boolean expectedResult) {
        ABCValidator validator = new ABCValidator();
        Whitebox.setInternalState(validator, &quot;abcRestClient&quot;, search);
        output = validator.validateABC(input);
        Assert.assertEquals(expectedResult, output);
    }
}

huangapple
  • 本文由 发表于 2020年5月4日 23:49:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/61596249.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定