I am writing a test case where in I want to run a one DataPoint for one test case and second DataPoint for second test case.
#RunWith(Theories.class)
public class DummyTest {
#DataPoints
public static String[] getFileNames() {
return new String[] { "firstFile.txt","firstFile1.txt" };
}
#Theory
public void test1(String fileName) throws Exception {
System.out.println(fileName);
assertThat(true, is(equalTo(Boolean.TRUE)));
}
#DataPoints
public static String[] getSecondFileNames() {
return new String[] { "secondFile.txt","secondFile1.txt" };
}
#Theory
public void test2(String fileName) throws Exception {
System.out.println(fileName);
assertThat(true, is(equalTo(Boolean.TRUE)));
}
}
I want that for first test case my first datapoints i.e. getFileNames method is called and for second test case getSecondFileNames datapoints should be called. Can anybody suggest is this feasible?
Thanks,
Shekhar
As of the shortly-upcoming JUnit 4.12, you can now name sets of datapoints and require parameters to come only from that set, e.g.:
#RunWith(Theories.class)
public class DummyTest {
#DataPoints("fileNames1")
public static String[] getFileNames() {
return new String[] { "firstFile.txt","firstFile1.txt" };
}
#Theory
public void test1(#FromDataPoints("fileNames1") String fileName) throws Exception {
System.out.println(fileName);
assertThat(true, is(equalTo(Boolean.TRUE)));
}
#DataPoints("fileNames2")
public static String[] getSecondFileNames() {
return new String[] { "secondFile.txt","secondFile1.txt" };
}
#Theory
public void test2(#FromDataPoints("fileNames2") String fileName) throws Exception {
System.out.println(fileName);
assertThat(true, is(equalTo(Boolean.TRUE)));
}
}
This should exactly solve your problem :-).
You could implement your own ParameterSupplier, as explained here: http://blog.schauderhaft.de/2010/02/07/junit-theories/
Tests can be grouped into "fixtures", where a fixture is a set of code that shares the same setup. Put the tests for cases using the same datapoints together in the same class, so you have one class for each set of data.
Have you looked at JUnitParams? If you just want to pass parameters to methods, which is all that your example shows, it's a much cleaner option.
#RunWith(JUnitParamsRunner.class)
public class DummyTest {
public static String[] getFileNames() {
return new String[] { "firstFile.txt","firstFile1.txt" };
}
#Theory
public void test1(String fileName) throws Exception {
System.out.println(fileName);
assertThat(true, is(equalTo(Boolean.TRUE)));
}
#DataPoints
public static String[] getSecondFileNames() {
return new String[] { "secondFile.txt","secondFile1.txt" };
}
#Theory
public void test2(String fileName) throws Exception {
System.out.println(fileName);
assertThat(true, is(equalTo(Boolean.TRUE)));
}
}
Related
I have a constructor that may throw an IOException:
public MyClass(string url) throws IOException { ... }
Now I want to test of the exception is thrown in certain scenarios using a parameterized test. Can I annotate my test-method with a value for url and the expected exception, something like this?
#Test("https://myHost/not.existsing", expected = IOException.class)
#Test("https://myHost/whrong.fileextension", expected = IOException.class)
public void MyTest(String url)
{
Assert.Throws(expected);
}
Junit 4 supports Prameterized. Try this:
#RunWith(Parameterized.class)
public class Test {
#Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ "https://myHost/whrong.fileextension" },
{ "https://myHost/not.existsing"}
});
}
private String url;
public Test(String url) {
this.url = url;
}
#Test(expected = IOException.class)
public void test() throws IOException {
MyClass myClass = new MyClass(url);
}
}
My situation:
class Test {
private static void xxx(String s) throws SQLException {
System.out.println(s);
}
private static void yyy(Consumer<String> f) {
try {
f.apply('hello');
} catch (SQLException e) {
System.out.println("error");
}
}
public static void main(String args[])() {
yyy(xxx); // <-- not working!!
}
}
What I'm trying to do is to pass a static method as a parameter for another static method. I think that the correct way to declare the signature of the method yyy is with Consumer, but I'm not really sure about the other part, passing xxx as the parameter.
A possible solution I've found is to write
yyyy(s -> xxx(s));
But it looks ugly and it doesn't really work if xxx throws exceptions.
By using
yyy(Test::xxx);
I got this error
error: incompatible thrown types SQLException in method reference
You can use a method reference:
class Test {
private static void xxx(String s) {
//do something with string
}
private static void yyy(Consumer<String> c) {
c.accept("hello");
}
public static void zzz() {
yyy(Test::xxx);
}
}
You can try below code
class Test {
private static Consumer<String> xxx(String s) {
//do something with string
return null;// return Consumer for now passing null
}
private static void yyy(Consumer<String> f) {
//do something with Consumer
}
public static void zzz(){
yyy(xxx("hello"));
}
}
Jmockit is very powerful, but sometimes I cannot understand what it does behind the scene, so I have a question regarding jmockit. Hopefully the more experienced programmers on here could help shine some light on this situation :)
I have the following two classes in two separate files:
public class SmallClass {
String a;
SmallClass(String arg) throws Exception {
a = arg;
}
public String getString() {
return a;
}
}
And
public class BigClass {
private static final SmallClass smallClass;
static {
try {
smallClass = new SmallClass("dummy");
} catch (Exception e) {
throw new IllegalStateException("Could not initialized", e);
}
}
public static String getString() {
return smallClass.getString();
}
}
Now, I have a class to test BigClass:
public class BigClassTest {
#Test
public void testGet() throws Exception {
///CLOVER:OFF
new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception {
//Do nothing
}
#Mock
public String getString() {
return "dummyString";
}
};
///CLOVER:ON
Assert.assertEquals("dummyString", BigClass.getString());
}
#Test(expected = ExceptionInInitializerError.class)
public void testException() throws Exception {
///CLOVER:OFF
new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception{
throw new Exception("Mocked Exception");
}
};
///CLOVER:ON
BigClass.getString();
}
}
If I run each of these independently, then they each passes. But if I run the whole test file, then the first test fails with:
java.lang.NoClassDefFoundError: Could not initialize class BigClass
I also tried tearing down the mock after each test like this, but it doesn't help:
public class BigClassTest {
MockUp<SmallClass> smallClassMockUp;
#Test
public void testGet() throws Exception {
///CLOVER:OFF
smallClassMockUp = new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception {
//Do nothing
}
#Mock
public String getString() {
return "dummyString";
}
};
///CLOVER:ON
Assert.assertEquals("dummyString", BigClass.getString());
smallClassMockUp.tearDown();
}
#Test(expected = ExceptionInInitializerError.class)
public void testException() throws Exception {
///CLOVER:OFF
smallClassMockUp = new MockUp<SmallClass>() {
#Mock
public void $init(String string) throws Exception{
throw new Exception("Mocked Exception");
}
};
///CLOVER:ON
BigClass.getString();
smallClassMockUp.tearDown();
}
}
Any help would be appreciated. Thank you in advance!
The occurrence of NoClassDefFoundError, in a case like this, is not because the class wasn't found by the JVM (it was), but because its static initialization has failed (by throwing an exception or error from the execution of a static initializer). Once this happens, the class is left in an invalid/uninitialized state and cannot be used in the same JVM instance anymore.
For reference, see the "Initialization of classes and interfaces" section in the JLS.
Also, note that the order in which tests execute is not necessarily the textual order they appear in the test class. Here, testException (the second test) runs first. So, when testGet runs, the class is invalid and the JVM throws the error.
#RunWith(JUnitParamsRunner.class)
public class MySimpleTest {
private MyRec rec;
private Matrix matrix;
#Before
public void createRecognizerBeforeEveryExecution() {
rec = new MyRec();
matrix = MatrixUtils.createMatrixWithValues();
}
public static Iterable<Object[]> data() {
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
#Test
#Parameters(method = "data")
public void test1(String output, String input) {
rec.fun1(matrix);
assertEquals(output, rec.someFunction(input));
}
public static Iterable<Object[]> data2() {
return Arrays.asList(
new Object[]{"expectedothervalue1", "input1"},
new Object[]{"expectedothervalue2", "input2"}
);
}
#Test
#Parameters(method = "data2")
public void test2(String output, String input) {
rec.fun1(matrix);
rec.fun2(matrix);
assertEquals(output, rec.someFunction(input));
}
}
I'm trying to find out what is the proper way to make this test. I'd like to use parametrized test, because it's really convenient way.
So as you can see, in every test function I call some function (fun1 and fun2). But I need to call it only once per every test (e.g. before each parametrized test execution).
Is there any way to tell JUnitParams that it should execute other function before executing all of parametrized tests?
I can't use #Before annotation, because as you can see in test1 I'm not using fun2. It think it should be executed by separate function.
Solution 1:
As fun[1|2] does not depend on internal test state, try to place their invocations inside data and data2 methods accordingly.
public static Iterable<Object[]> data() {
rec.fun1(matrix);
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
public static Iterable<Object[]> data2() {
rec.fun1(matrix);
rec.fun2(matrix);
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
Solution 2:
Spliting test cases is not a best practice. Your test are harder to maintain. Flow is far more complicated. There is also a risk your tests start depends on each other. Duplication in tests sometimes is simply better.
PS:
If you are using Strings as test method parameters it's better to pass them exactly like in 25th line of this file:
https://github.com/Pragmatists/JUnitParams/blob/master/src/test/java/junitparams/usage/SamplesOfUsageTest.java instead of special methods.
#Test
#Parameters({"AAA,1", "BBB,2"})
public void paramsInAnnotation(String p1, Integer p2) { }
I decided to use TestNG to resolve this problem (code just to show my train of thought):
import org.testng.Assert;
import org.testng.annotations.*;
import java.lang.reflect.Method;
public class TempTest {
private Integer number;
#BeforeMethod
public void init(Method m) {
number = 5;
switch(m.getName()) {
case "test2":
fun(10);
fun2(5);
break;
case "test1":
fun(10);
break;
}
}
public void fun(int value) {
number += value;
}
public void fun2(int value) {
number -= value;
}
#Test
public void test1() {
Assert.assertEquals(new Integer(15), number);
}
#Test
public void test2() {
Assert.assertEquals(new Integer(10), number);
}
#Test
public void test3() {
Assert.assertEquals(new Integer(5), number);
}
}
I am trying to use Google ThreadWeaver to write a unit test for concurrent code. No matter what I do, I will get an IllegalArgumentException. I am still working with an example, but even that does not work. This is what I tried:
public class ExampleTest {
public static class ExampleMain implements MainRunnable<Example> {
private Example example;
#Override
public Class<Example> getClassUnderTest() {
return Example.class;
}
#Override
public String getMethodName() {
return null;
}
#Override
public Method getMethod() throws NoSuchMethodException {
return null;
}
#Override
public void initialize() throws Exception {
example = new Example();
}
#Override
public Example getMainObject() {
return example;
}
#Override
public void terminate() throws Exception {
}
#Override
public void run() throws Exception {
example.test("second");
}
}
public static class ExampleSecondary implements SecondaryRunnable<Example, ExampleMain> {
private ExampleMain exampleMain;
#Override
public void initialize(ExampleMain main) throws Exception {
exampleMain = main;
}
#Override
public void terminate() throws Exception {
}
#Override
public boolean canBlock() {
return false;
}
#Override
public void run() throws Exception {
exampleMain.getMainObject().test("main");
}
}
public static class Example {
private List<String> list = new ArrayList<String>();
public String test(String s) {
System.out.println("1" + s);
list.add(s);
System.out.println("2" + s);
return list.get(0);
}
}
#Test
public void testThreadWeaver() throws Exception {
ClassInstrumentation instrumentation = Instrumentation.getClassInstrumentation(Example.class);
Method tested = Example.class.getDeclaredMethod("test", String.class);
Method breakpoint = List.class.getDeclaredMethod("add", Object.class);
CodePosition codePosition = instrumentation.afterCall(tested, breakpoint);
InterleavedRunner.interleave(new ExampleMain(), new ExampleSecondary(), Arrays.asList(codePosition)).throwExceptionsIfAny();
}
}
The stack trace says:
java.lang.IllegalArgumentException: Class Example is not instrumented
at
com.google.testing.threadtester.CallLoggerFactory.getClassInstrumentation(CallLoggerFactory.java:108)
at
com.google.testing.threadtester.Instrumentation.getClassInstrumentation(Instrumentation.java:65)
at MyTest.testThreadWeaver(MyTest.java:92
I followed the instructions at the official Google code webpage, but it does not seem to work. Any ideas?
ThreadWeaver needs to instrument your classes in order to add breakpoints to your methods. Therefore, you cannot run the tests with JUnit directly but you must run your test from a specific test runner. For your case this would be ThreadedTestRunner. The actual test methods must then be annotated with #ThreadedTest instead of #Test. This should work:
#Test
public void startTest() throws Exception {
new ThreadedTestRunner().runTests(getClass(), Example.class);
}
#ThreadedTest
public void testThreadWeaver() throws Exception {
// here comes your test
}