I have some test suites that in essence looks like
#Test
public void test1_2() {
test(1,2);
}
#Test
public void test1_3() {
test(1,3);
}
#Test
public void test4_5() {
test(4,5);
}
#Test
public void test4_9() {
test(4,9);
}
// and so forth
private void test(int i, int j) throws AssertionError{
// ...
}
(This is not the actual tests, but the essence, each #Test method only calls one method)
So my thinking was that I could use #RunWith for a custom BlockJUnit4ClassRunner which accepts a List of jUnit Runners.
How would this be achived? Or is there a better way to do it?
Why not use #Parameter ?
#RunWith(Parameterized.class)
public class YourTest{
private int i;
private int j;
public Parameter(int i, int j) {
this.i= i;
this.j= j;
}
#Parameters
public static Collection<Object[]> data() {
Object[][] data = new Object[][] { { 1, 2 }, { 1,3 }, { 4,5 }, { 4,9 } };
return Arrays.asList(data);
}
#Test
public void test() throws InterruptedException {
//use i & j
}
}
This looks to me like something that should be done with Theories. Otherwise, you could use Enclosed to have multiple inner classes each with its own runner.
Related
I wanted to check if we can create a function name from variable value in C#. Here is what I am trying. I have a list of strings as below:
private List<string> _pages;
_pages.AddRange(new string[] { "Page1", "Page2", "Page3", "Page4"});
And I have tasks like below:
private async void Sync_Page1() {}
private async void Sync_Page2() {}
private async void Sync_Page3() {}
private async void Sync_Page4() {}
For each of those strings in the list, I need to call a method like below
foreach (string pageName in _pages)
{
Task.Run(async () => { Sync_pageName() }); // where pageName will be the items from list.
}
Tried searching on google but didn't find anything specific. So not sure if that can be done in C# but was wondering if there is a possibility.
Any thoughts?
You can map it to dictionary items which you can invoke :
namespace ConsoleApp1
{
class Program
{
public static void Main(String[] args)
{
PagesExecution pe = new PagesExecution();
pe.Execute();
Console.ReadLine();
}
}
public class PagesExecution
{
//Action<string> a = new Action<string>();
private List<string> _pages = new List<string>();
private Dictionary<string, Action> dictionary = new Dictionary<string, Action>();
public PagesExecution ()
{
}
public void Execute()
{
dictionary.Add("Page1", new Action(Sync_Page1));
dictionary.Add("Page2", Sync_Page2);
dictionary.Add("Page3", Sync_Page3);
dictionary.Add("Page4", Sync_Page4);
_pages.AddRange(new string[] { "Page1", "Page2", "Page3", "Page4"});
foreach (var entry in _pages)
{
dictionary[entry].Invoke();
}
}
public void Sync_Page1()
{
Console.WriteLine("Page1");
}
private void Sync_Page2()
{
Console.WriteLine("Page2");
}
private void Sync_Page3()
{
Console.WriteLine("Page3");
}
private void Sync_Page4()
{
Console.WriteLine("Page4");
}
}
}
For Example:
Class A{
string s = null;
public void method(){
s="Sample String";
}
}
I have a void method with similar scenario. How can I test such void method?
With void methods you should test the interaction with its dependent objects within the void method. I think a void method with no argument is rarely useful to test (but if you have a valid use case, please add it to your question). I provided you a simple example for a method with an argument but void as a return type:
public class A {
private DatabaseService db;
private PaymentService payment;
// constructor
public void doFoo() {
if(n < 2) {
db.updateDatabase();
} else {
payment.payBill();
}
}
}
And the unit test for this can look like the following
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#Mock
DatabaseService db;
#Mock
PaymentService payment;
#Test
public void testDoFooWithNGreaterTwo() {
A cut = new A(db, payment); // cut -> class under test
cut.doFoo(3);
verify(payment).payBill(); // verify that payment was called
}
#Test
public void testDoFooWithNLessThanTwo() {
A cut = new A(db, payment); // cut -> class under test
cut.doFoo(1);
verify(db).updateDatabase(); // verify that db was called
}
}
Testing your program
Create a class called Demo.java. This class will contain your main method
Create an instance of your class (an object) by using the default constructor.
Call all your objects setter (mutator) methods to assign values to your object
Call the objects display method, to print out it's values
Create another instance of your class (another object) by using the parameterized constructor
Call the objects display method, to print out it's values
public class Shoes {
//Instance Variables
private String brand;
private int cost;
private double size;
// Default Constructor
public Shoes(){
brand = "";
cost = 0;
size = 0;
}
//Constructor
public Shoes (String brand, int cost, double size)
{
this.brand = brand;
this.cost = cost;
this.size = size;
}
//Setter
public void setBrand (String brand)
{
this.brand=brand;
}
public void setCost (int cost)
{
this.cost=cost;
}
public void setSize (double size)
{
this.size=size;
}
//Getter
public String getBrand()
{
return brand;
}
public int getCost()
{
return cost;
}
public double getSize()
{
return size;
}
// Display data
public void display()
{
System.out.println(brand);
System.out.println(cost);
System.out.println(size);
}
}
public class Demo {
public static void main(String[] args) {
// Create a object
Shoes yeezys = new Shoes();
Shoes kobes = new Shoes();
yeezys.setBrand("Adidas");
yeezys.setCost(200);
yeezys.setSize(8.5);
yeezys.display();
System.out.println("");
//Second object? Need help with this
kobes.setBrand("Nike");
kobes.setCost(150);
kobes.setSize(9.5);
kobes.display();
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Running junit tests in parallel?
I found the test cases inside jUnit are executed in sequence, how to make them execute in parallel?
Junit4 provides parallel feature using ParallelComputer:
public class ParallelComputerTest {
#Test
public void test() {
Class[] cls={ParallelTest1.class,ParallelTest2.class };
//Parallel among classes
JUnitCore.runClasses(ParallelComputer.classes(), cls);
//Parallel among methods in a class
JUnitCore.runClasses(ParallelComputer.methods(), cls);
//Parallel all methods in all classes
JUnitCore.runClasses(new ParallelComputer(true, true), cls);
}
public static class ParallelTest1 {
#Test public void a(){}
#Test public void b(){}
}
public static class ParallelTest2 {
#Test public void a(){}
#Test public void b(){}
}
}
Here is some sample code. This works for me really well. ExecutorService.
public class TestCases {
static ExecutorService exe ;
public static void main(String[] args) throws Throwable {
test1() ;
test2() ;
test3() ;
}
public static void test1() {
exe = Executors.newCachedThreadPool() ;
for (int i = 0 ; i < 10 ; i++) {
Test1 test1 = new Test1() ;
exe.execute(test1) ;
}
exe.shutdown() ;
while(!exe.isShutDown()) {
}
}
//same for test2 and test3
}
public class Test1 implements Runnable {
public Test1() {
}
#Test
public myTest throws Throwable {
}
}
Can I have more than one method with #Parameters in junit test class which is running with Parameterized class ?
#RunWith(value = Parameterized.class)
public class JunitTest6 {
private String str;
public JunitTest6(String region, String coverageKind,
String majorClass, Integer vehicleAge, BigDecimal factor) {
this.str = region;
}
#Parameters
public static Collection<Object[]> data1() {
Object[][] data = {{some data}}
return Arrays.asList(data);
}
#Test
public void pushTest() {
System.out.println("Parameterized str is : " + str);
str = null;
}
#Parameters
public static Collection<Object[]> data() {
Object[][] data = {{some other data}}
return Arrays.asList(data);
}
#Test
public void pullTest() {
System.out.println("Parameterized new str is : " + str);
str = null;
}
}
You can use the Theories runner (search for the word theories at that link) to pass different parameters to different methods.
Probably the data1 method, but no guarantee of that, it'll use whichever one the JVM gives junit4 first.
Here's the relevant code from junit:
private FrameworkMethod getParametersMethod(TestClass testClass) throws Exception {
List<FrameworkMethod> methods= testClass.getAnnotatedMethods(Parameters.class);
for (FrameworkMethod each : methods) {
int modifiers= each.getMethod().getModifiers();
if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))
return each;
}
throw new Exception("No public static parameters method on class " + testClass.getName());
}
So the first public, static annotated method that it finds will be used, but it may find them in any order.
Why do you have uour test written that way? You should only have one #Parameters-annotated method.
It's not designated to have more than one data method. You can see it in skaffman's answer.
Why it's not provided to implement two data methods?
The answer could be: Coupling.
Is it too complex to split this test up into two testcases? You would be able to introduce a small inheritance and share common methods. With two testcases you could provide two separated data methods and test your stuff very well.
I hope it helps.
You can create inner classes for each set of methods that operate on the same parameters. For example:
public class JunitTest6 {
#RunWith(value = Parameterized.class)
public static class PushTest{
private String str;
public PushTest(String region) {
this.str = region;
}
#Parameters
public static Collection<Object[]> data() {
Object[][] data = {{some data}}
return Arrays.asList(data);
}
#Test
public void pushTest() {
System.out.println("Parameterized str is : " + str);
str = null;
}
}
#RunWith(value = Parameterized.class)
public static class PullTest{
private String str;
public PullTest(String region) {
this.str = region;
}
#Parameters
public static Collection<Object[]> data() {
Object[][] data = {{some other data}}
return Arrays.asList(data);
}
#Test
public void pullTest() {
System.out.println("Parameterized new str is : " + str);
str = null;
}
}
}