如何使jUnit类具有参数 [英] How to make jUnit class have parameter
问题描述
在将像mvc概念之类的bean类传递给jUnit类时遇到问题.我不想更改结构jUnit类,因为我需要它.
DataBean类
public class DataBean {
private String browserName;
private String userName;
public String getBrowserName() {
return browserName;
}
public void setBrowserName(String browserName) {
this.browserName = browserName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
主要班级
public class Main {
public static void main(String[] args) {
String[] arrBrowserName = {"chrome", "firefox"};
String[] arrUserName = {"user1", "user2"};
for(int i=0; i<2; i++) {
DataBean dataBean = new DataBean();
String browserName = arrBrowserName[i];
String userName = arrUserName[i];
dataBean.setBrowserName(browserName);
dataBean.setUserName(userName);
//How to call "TestCase1", include passing the "databean"
JUnitCore junit = new JUnitCore();
junit.run(TestCase1.class);
}
}
}
TestCase1类
public class TestCase1 {
DataBean dataBean = new DataBean();
//Here, how to do ? i want to get "databean" from "Main" class, without change this is class as jUnit
@Before
public void setUp(){
//set up based on data from "Main class"
}
@Test
public void scenario(){
//
}
@After
public void tearDown(){
//
}
}
根据上面的代码,假设我有2个数据作为数据测试,我想基于Main类中的数据设置before
.我将参数放置在TestCase1
中的什么位置,以便可以获取databean
?这可能吗?
仅供参考,DataBean对象是一种叫做 anemic 对象的气味.
这是一个DTO(传输数据的对象),因此,除非某些框架要求,否则请尝试使它们保持不变,或者至少要明确指出没有封装:
public class DataBean {
public String browserName;
public String userName;
}
无论如何,似乎您正在尝试对测试进行参数化.
鉴于测试对象是由JUnit构建的,您将不得不使用JUnit提供的API更改测试类,以注入所需的对象/数据.
您可以使用ThreadLocal存储绕过框架API,但我根本不建议这样做.
如果您使用JUnit,请以JUnit的方式进行操作.
假设您仍在使用JUnit4,则可以(至少)采用两种方法:
首先,使用JUnit4内置运行器Parameterized
进行参数化的测试类:
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class BrowserTest {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{new DataBean("chrome", "user1")},
{new DataBean("firefox", "user2")}
});
}
private final DataBean dataBean;
public BrowserTest(DataBean dataBean) {
this.dataBean = dataBean;
}
@Test
public void test() {
// Test using a dataBean instance
}
}
第二,将第三个名为 JUnitParams 的库与运行程序JUnitParamsRunner一起使用,并设置参数化 test 的测试方法:
import org.junit.Test;
import org.junit.runner.RunWith;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
@RunWith(JUnitParamsRunner.class)
public class BrowserTest {
@Test
@Parameters(method = "test_cases")
public void test(DataBean dataBean) {
// Test using a dataBean instance
}
public static Object[] test_cases() {
return new Object[]{
new DataBean("chrome", "user1"),
new DataBean("firefox", "user2")
};
}
}
最后,有一个新版本 JUnit5 ,它的扩展模型发生了很大的变化,因为它允许要素的组成(而不是只有一个跑步者). /p>
使用JUnit5,可以像这样编写相同的测试:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
class BrowserTest {
@ParameterizedTest
@CsvSource({
"chrome, user1",
"firefox, user2"
})
void test(String browserName, String userName) {
// Test using a dataBean instance
}
}
希望这会有所帮助!
I have problem with passing a bean class like mvc concept to implement to jUnit class. I don't want change the structure jUnit class, because i have need it.
Class DataBean
public class DataBean {
private String browserName;
private String userName;
public String getBrowserName() {
return browserName;
}
public void setBrowserName(String browserName) {
this.browserName = browserName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
Class Main
public class Main {
public static void main(String[] args) {
String[] arrBrowserName = {"chrome", "firefox"};
String[] arrUserName = {"user1", "user2"};
for(int i=0; i<2; i++) {
DataBean dataBean = new DataBean();
String browserName = arrBrowserName[i];
String userName = arrUserName[i];
dataBean.setBrowserName(browserName);
dataBean.setUserName(userName);
//How to call "TestCase1", include passing the "databean"
JUnitCore junit = new JUnitCore();
junit.run(TestCase1.class);
}
}
}
Class TestCase1
public class TestCase1 {
DataBean dataBean = new DataBean();
//Here, how to do ? i want to get "databean" from "Main" class, without change this is class as jUnit
@Before
public void setUp(){
//set up based on data from "Main class"
}
@Test
public void scenario(){
//
}
@After
public void tearDown(){
//
}
}
Based on the above code, let's say i have 2 data as data testing, i want setup the before
based on the data from Main class. Where is i placement the parameter in TestCase1
so that I can get databean
? and is this possible?
FYI, the DataBean object is a smell called anemic object.
It is a DTO (object to transport data), so except when required by some framework, try to keep these immutable, or at least make it explicit that there is no encapsulation:
public class DataBean {
public String browserName;
public String userName;
}
Anyway, it seems that you are trying to parameterize a test.
Given that the test object is built by JUnit, you will have to change the test class using the API provided by JUnit to inject the needed object/data.
You could use a ThreadLocal storage to bypass the framework API, but I do not recommand it at all.
If you use JUnit, do it the JUnit way.
Assuming that you still use JUnit4, you can go (at least) two ways:
First, using JUnit4 built-in runner Parameterized
, making a test class parameterized:
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class BrowserTest {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{new DataBean("chrome", "user1")},
{new DataBean("firefox", "user2")}
});
}
private final DataBean dataBean;
public BrowserTest(DataBean dataBean) {
this.dataBean = dataBean;
}
@Test
public void test() {
// Test using a dataBean instance
}
}
Second, use a third library called JUnitParams with the runner JUnitParamsRunner, making a test method parameterized:
import org.junit.Test;
import org.junit.runner.RunWith;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
@RunWith(JUnitParamsRunner.class)
public class BrowserTest {
@Test
@Parameters(method = "test_cases")
public void test(DataBean dataBean) {
// Test using a dataBean instance
}
public static Object[] test_cases() {
return new Object[]{
new DataBean("chrome", "user1"),
new DataBean("firefox", "user2")
};
}
}
Finally, there is the new version, JUnit5 which changes a lot regarding its extention model as it allows composition of features (instead of having only one runner).
With JUnit5, the same test can be written like this:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
class BrowserTest {
@ParameterizedTest
@CsvSource({
"chrome, user1",
"firefox, user2"
})
void test(String browserName, String userName) {
// Test using a dataBean instance
}
}
Hope this helps !
这篇关于如何使jUnit类具有参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!