2012-07-11 24 views
8

Tôi đang sử dụng tính năng "parametrized" của junit 4 và tôi nhận thấy rằng phương thức @parameters được thực thi trước phương thức @beforeclass. Điều này tạo ra một vấn đề đối với tôi bởi vì các tham số tôi đang chuyển sang các trường hợp thử nghiệm thông qua @parameters phụ thuộc vào mã khởi tạo trong phương thức @beforeclass. Ví dụ@parameters được thực hiện trước phương thức @beforeclass

@RunWith(Parameterized.class) 
public class TestOtherClass { 

    String argument; 
    private static boolean initializeThis; 

    public TestOtherClass(String parameter) throws Exception { 
     argument=parameter; 
    } 

    @BeforeClass 
    public static void doSetup() { 
     System.out.println("Doing setup before class..."); 
     initializeThis=true; // true or false, based on some condition 
    } 

    @Test 
    public void otherTest() { 
     System.out.println("Other test: " + argument); 
    } 

    @Parameters 
    public static Collection<Object[]> getData(){ 
     System.out.println("Inside parameter"); 
     String addThis; 
     if(initializeThis) 
      addThis="adding true"; 
     else 
      addThis="adding false"; 

     Object[] para1 = new Object[]{"First parameter :: " + addThis}; 
     Object[] para2 = new Object[]{"Second parameter :: " + addThis}; 

     Collection<Object[]> classNames = new ArrayList<Object[]>(); 
     classNames.add(para1); 
     classNames.add(para2); 
     return classNames; 
    } 
} 

Bây giờ, tôi đang khởi tạo biến "initializeThis" true trong phương pháp @beforeclass nhưng (ngạc nhiên) khi tôi thực hiện các trường hợp thử nghiệm nó in

Other test: First parameter :: adding false 
Other test: Second parameter :: adding false 

Đó là một cái gì đó không mong đợi.
Câu hỏi của tôi là; có cách nào để thực thi phương thức @beforeclass trước @parameters, chúng ta có thể thực hiện điều này trong junit 4 không?

+0

có thể chuyển chức năng của nhà cung cấp cho các tham số có thể truy xuất trường sau – Kirby

Trả lời

1

JUnit tạo một Runner cho mỗi mục trong danh sách tham số, Runner là những gì gói gọn phương pháp thử nghiệm. Vì vậy, @Parameters sẽ luôn được thực hiện trước @BeforeClass.

Tuy nhiên, bạn có thể kết hợp @Parameterized với Assume. Bạn luôn bao gồm tất cả các tham số trong danh sách của mình, cho dù bạn có định thực hiện nó hay không. Sau đó, trong phương pháp thử, hãy thêm assumeTrue() để kiểm tra giá trị initializeThis.

@RunWith(Parameterized.class) 
public class TestOtherClassAssume { 
    private final String argument; 
    private final boolean initializeThisTest; 
    private static boolean initializeThis; 

    @Parameters 
    public static Collection<Object[]> getData(){ 
    System.out.println("Inside parameter"); 

    return Arrays.asList(new Object[][] { 
     { false, "First" }, 
     { true, "Second" }, 
    }); 
    } 

    public TestOtherClassAssume(boolean initializeThisTest, String argument) { 
    this.initializeThisTest = initializeThisTest; 
    this.argument = argument; 
    } 

    @BeforeClass 
    public static void doSetup() { 
    System.out.println("Doing setup before class..."); 
    initializeThis = true; // true or false, based on some condition 
    } 

    @Test 
    public void otherTest() { 
    Assume.assumeTrue(initializeThis == initializeThisTest); 
    System.out.println("Other test: " + argument); 
    } 
} 

Kết quả từ này là:

Inside parameter 
Doing setup before class... 
Other test: Second 
5

Tôi sẽ sử dụng chỉ đơn giản cũ java tĩnh {..} initializer thay vì @BeforeClass, ví dụ:

@RunWith(Parameterized.class) 
public class TestOtherClass { 

    String argument; 
    private static boolean initializeThis; 

    public TestOtherClass(String parameter) throws Exception { 
     argument=parameter; 
    } 

    static { 
     doSetup(); 
    } 

    // @BeforeClass 
    public static void doSetup() { 
     System.out.println("Doing setup before class..."); 
     initializeThis=true; // true or false, based on some condition 
    } 

    @Test 
    public void otherTest() { 
     System.out.println("Other test: " + argument); 
    } 

    @Parameters 
    public static Collection<Object[]> getData(){ 
     System.out.println("Inside parameter"); 
     String addThis; 
     if(initializeThis) 
      addThis="adding true"; 
     else 
      addThis="adding false"; 

     Object[] para1 = new Object[]{"First parameter :: " + addThis}; 
     Object[] para2 = new Object[]{"Second parameter :: " + addThis}; 

     Collection<Object[]> classNames = new ArrayList<Object[]>(); 
     classNames.add(para1); 
     classNames.add(para2); 
     return classNames; 
    } 
} 

chỉ có nhược điểm tôi biết rằng các lớp được kế thừa từ điều này sẽ không thể ghi đè lên trình khởi tạo tĩnh, trong khi @BeforeClass mang lại một số quyền tự do trong khía cạnh này;

0

Tuy nhiên, điều này không hoạt động với TestSuites. Với

@RunWith(Parameterized.class) 
public class TogglableParameterizedTest { 
    static boolean useAllParameters = false; 

    int parameter; 

    public TogglableParameterizedTest(int parameter) { 
     super(); 
     this.parameter = parameter; 
    } 
    @Parameters 
    public static Collection<Object[]> getTestParameters() { 
     List<Object[]> parameters = new ArrayList<Object[]>(); 
     if(useAllParameters) { 
      parameters.add(new Object[] { 1 }); 
      parameters.add(new Object[] { 2 }); 
      parameters.add(new Object[] { 3 }); 
     } 
     else { 
      parameters.add(new Object[] { 1 }); 
     } 
     return parameters; 
    } 
    @Test 
    public void test() { 
     System.out.println("parameter=" + parameter); 
    } 
} 

này không hoạt động:

@RunWith(Suite.class) 
@SuiteClasses({ TogglableParameterizedTest.class }) 
public class NonWorkingTestSuite1 { 

    @BeforeClass 
    public static void toggle() { 
     System.out.println("sets flag to late!"); 
    } 

} 

Đầu ra là

sets flag to late! 
parameter=1 

Cũng không phải rằng:

@RunWith(Suite.class) 
@SuiteClasses({ TogglableParameterizedTest.class }) 
public class NonWorkingTestSuite2 { 
    static { 
     System.out.println("sets flag still to late"); 
     TogglableParameterizedTest.useAllParameters = true; 
    } 
} 

Đầu ra là "tham số = 1". Vì vậy, bộ khởi tạo tĩnh không được thực thi chút nào. Tôi tìm thấy cách giải quyết sau. Mở rộng "Suite" và chèn initializer tĩnh có:

public class TogglingSuite extends Suite { 

    static { 
     System.out.println("sets flag early enough!"); 
     TogglableParameterizedTest.useAllParameters = true; 
    } 

    public TogglingSuite(Class<?> klass, Class<?>[] suiteClasses) 
     throws InitializationError { 
     super(klass, suiteClasses); 
    } 

    public TogglingSuite(Class<?> klass, List<Runner> runners) 
     throws InitializationError { 
     super(klass, runners); 
    } 

    public TogglingSuite(Class<?> klass, RunnerBuilder builder) 
      throws InitializationError { 
     super(klass, builder); 
    } 

    public TogglingSuite(RunnerBuilder builder, Class<?> klass, 
      Class<?>[] suiteClasses) throws InitializationError { 
     super(builder, klass, suiteClasses); 
    } 

    public TogglingSuite(RunnerBuilder builder, Class<?>[] classes) 
      throws InitializationError { 
     super(builder, classes); 
    } 
} 

và sử dụng nó trong bộ kiểm tra của bạn:

@RunWith(TogglingSuite.class) 
@SuiteClasses({ TogglableParameterizedTest.class }) 
public class WorkingTestSuite { 

} 

Đầu ra là

sets flag early enough! 
parameter=1 
parameter=2 
parameter=3 

Bây giờ nó hoạt động.

4

Đây là câu hỏi cũ nhưng gần đây tôi gặp sự cố tương tự. Nó cho tôi thấy rằng không có giải pháp nào dường như là giải pháp rõ ràng nhất - gọi phương thức @BeforeClass trong phương thức @Parameters. Cái sau là tĩnh và được thực thi chỉ một lần - trước khi bất kỳ thử nghiệm nào được chạy. Vì vậy, nó là cho tất cả các ý định và mục đích một phương pháp @BeforeClass mặc dù nó không được chú thích như vậy. Bạn có thể tìm thêm chi tiết tại đây: http://feraldeveloper.blogspot.co.uk/2013/12/beforeclass-and-parametrized-junit-tests.html

+0

Thật không may điều này không hoạt động nếu thử nghiệm của bạn yêu cầu thư mục '@ClassRule public static TemporaryFolder = new TemporaryFolder();' ngay cả ClassRule được khởi tạo sau khi phương thức được chú thích bằng @Parameters (https://github.com/junit-team/junit4/issues/527) –

Các vấn đề liên quan