简体   繁体   English

JUnit:如何通过构造函数创建具有依赖注入的测试类

[英]JUnit: How to create a test class with dependency injection via the constructor

How can I create a test class where I can inject the class to be used for testing?如何创建一个测试类,我可以在其中注入用于测试的类?

For example, let's say I have a interface ISort and some concrete classes InsertionSort , MergeSort , etc which implement ISort .例如,假设我有一个接口ISort和一些实现ISort具体类InsertionSortMergeSort等。 Since the test cases for all ISort are the same, How can I write a common test class and inject the concrete class to be tested?由于所有ISort的测试用例都相同,如何编写一个通用的测试类并注入要测试的具体类?

This is what I have tried so far这是我迄今为止尝试过的

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class SortTest {

    private ISort sortingAlgorithm;

    public SortTest(ISort sortingAlgorithm) {
        this.sortingAlgorithm = sortingAlgorithm;
    }

    @Test
    public void test1() {
        int[] data = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] expected = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        assertArrayEquals(expected, sortingAlgorithm.sort(data));
    }

    @Test
    public void test2() {
        int[] data = new int[] {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
        int[] expected = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        assertArrayEquals(expected, sortingAlgorithm.sort(data));
    }

    // .. more tests
}

How to run tests from SortTest using InsertionSortTest class ?如何使用InsertionSortTest类从SortTest运行测试?

class InsertionSortTest {
    // ??
}

Maybe something like this would do the trick.也许这样的事情可以解决问题。

private static Stream<ISort> sortingType() {
    return Stream.of(new InsertionSort(), new MergeSort());
}

@ParameterizedTest
@MethodSource("sortingType")
public void test1(ISort sortingAlgorithm) {
        int[] data = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] expected = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        assertArrayEquals(expected, sortingAlgorithm.sort(data));
}

Have you tried Factory Pattern ?你试过Factory Pattern吗? Let's create a SortFactory让我们创建一个 SortFactory

public class SortFactory {

public ISort getSortingMethod(String method) {
    if(method == null) {
        return null;
    }
    if(method.equalsIgnoreCase("InsertionSort")) {
        return new InsertionSort();
    }

    if(method.equalsIgnoreCase("MergeSort")) {
        return new MergeSort();
    }

    return null;
}
}

and then in your test class, you can use like this然后在你的测试课中,你可以像这样使用

public class SortTest {

private ISort sortingAlgorithm;
private SortFactory sortFactory = new SortFactory();    


@Test
public void test1() {
    int[] data = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int[] expected = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    sortingAlgorithm = sortFactory.getSortingMethod("MergeSort");
    assertArrayEquals(expected, sortingAlgorithm.sort(data));
}

@Test
public void test2() {
    int[] data = new int[] { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
    int[] expected = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    sortingAlgorithm = sortFactory.getSortingMethod("InsertionSort");
    assertArrayEquals(expected, sortingAlgorithm.sort(data));
}
}

Could be done using @Parameterized .可以使用@Parameterized完成。 You will probably more documentation, just a head start, also using a factory:您可能会获得更多文档,只是一个开端,也使用工厂:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class MyTest {

    private static interface SortFactory {
        ISort get();
    }

    private String someOtherParam; // example for more data

    private SortFactory sortFactory;

    public MyTest(SortFactory factory, String someOtherParam) {
        this.sortFactory = factory;

        this.someOtherParam = someOtherParam;
    }

    @Parameterized.Parameters(name = "{1}") // string to show in output to identify tests, here the second parameter
    public static Collection<Object[]> getTestdata() {
        List<Object[]> parameters = new ArrayList<Object[]>();
        parameters.add(new Object[]{ new SortFactory() {
            @Override
            public ISort get() {
                return new MergeSort();
            }
        }, "merge" });
        parameters.add(new Object[]{ new SortFactory() {
            @Override
            public ISort get() {
                return new InsertionSort();
            }
        }, "insertion" });
        return parameters;
    }

    @Test
    public void testSort() {
        int[] given = new int[]{ 2, 1 };

        int[] expected = new int[]{ 1, 2 };

        int[] actual = sortFactory.get().sort(given);

        assertArrayEquals(expected, actual);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用非默认构造函数和依赖注入为类创建 Mockito 测试 - Create Mockito test for class with non default constructor and dependency injection 如何通过Spring依赖注入为Jersey Rest编写JUnit测试用例 - How to write junit test cases for Jersey rest with spring dependency injection 如何为手动依赖注入创建mockito测试 - How to create mockito test for Manual dependency injection Spring依赖注入到具有构造函数的类 - Spring dependency injection to a class with a constructor 如何在构造函数中通过依赖注入应用logger而没有框架 - how to apply logger via dependency injection in constructor and no frameworks 在junit测试中未发生@Autowired依赖项注入 - @Autowired dependency injection not occurring in junit test 依赖项列表的 JUnit 测试构造函数注入 - JUnit Test Constructor Injection of List of Dependencies 依赖注入如何在没有构造函数的情况下实例化一个类? - How does dependency injection instantiate a class without constructor? 如何获取在其构造函数中使用依赖注入的类的实例 - How to get instance of class that uses dependency injection in its constructor 如何在抽象 class 中使用构造函数注入注入特定依赖项? - How to inject specific dependency using constructor injection in an abstract class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM