如何使jUnit类具有参数 [英] How to make jUnit class have parameter

查看:71
本文介绍了如何使jUnit类具有参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将像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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆