0
  • Its my first projet in Maven, i have code like in below and, How can i edit my code to run tests, with parameters that I sorted in main. I wonna to write test with parameters a and b, I tried getters but didnt work. How can I extract this varaibles ?

MAIN

import org.junit.Before;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.ToIntBiFunction;

import static jdk.xml.internal.SecuritySupport.getContextClassLoader;

public class Calculator {
    private Calculator calculator;

    @Before
    void setUp() throws IOException{
        try {
            InputStream in = getContextClassLoader().getResourceAsStream("src/file.txt");
            calculator = new Calculator(in);
            List<String> list = Files.readAllLines(Paths.get("src/file.txt"));
            int apply = Integer.valueOf(list.get(list.size() - 1).split(" ")[1]);
            Map<String, ToIntBiFunction<Integer, Integer>> map = prepMap();
            for (int i = 0; i < list.size() - 1; i++) {
                apply = map.get(list.get(i).split(" ")[0]).applyAsInt(apply, Integer.valueOf(list.get(i).split(" ")[1]));
            }
            System.out.println(apply);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public int add(int a, int b) {
        return a+b; }

    public int subtract(int a, int b) {
        return a-b;
    }

    public int multiply(int a, int b) {
        return a*b;
    }

    public int divide(int a, int b) {
        return a/b;
    }

    public Map<String, ToIntBiFunction<Integer, Integer>> prepMap() {
        Map<String, ToIntBiFunction<Integer, Integer>> map = new HashMap<>();
        map.put("multiply", (a, b) -> a * b);
        map.put("add", (a, b) -> a + b);
        map.put("devide", (a, b) -> {
            if (b == 0) {
                System.out.println("deviding by 0\nskiping this opperation");
                return a;
            }
            return a / b;
        });
        map.put("subtract", (a, b) -> a - b);
        return map;
    }

}



Example for testing file add 2 multiply 3 apply 10

My Tests


import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.function.ToIntBiFunction;
import java.util.logging.Logger;
import static org.assertj.core.api.Assertions.assertThat;

public class CalculatorTests extends Calculator{
    private static Logger LOGGER = Logger.getLogger("InfoLogging");
    private String path= "src/file.txt";

    public CalculatorTests(String path) {
        super(path);
    }


    @Test
    public void testAdd() {
        LOGGER.info("Running When Case1: testAdd");
        //given
        Calculator calculator = new Calculator(path);
        //when
        Scanner sc1 = new Scanner(path);
        Scanner sc2 = new Scanner(path);
        int result = calculator.add(10, 2);
        //then
        assertThat(result).isEqualTo(12);
    }
    @Test
    public void testSubtract() {
        LOGGER.info("Running When Case2: testSubtract");

        //given
        Calculator calculator = new Calculator(path);

        //when
        int result = calculator.subtract(3, 1);

        //then
        assertThat(result).isEqualTo(2);
    }
    @Test
    public void testMultiply() {
        LOGGER.info("Running When Case3: testMultiply");

        //given
        Calculator calculator = new Calculator(path);

        //when
        int result = calculator.multiply(12, 3);

        //then
        assertThat(result).isEqualTo(36);
    }
    @Test
    public void testDivide() {
        LOGGER.info("Running When Case4: testDivide");
        //given
        Calculator calculator = new Calculator(path);

        //when
        int result = calculator.divide(4,2);

        //then
        assertThat(result).isEqualTo(2);
    }
}

I was trying with scanners too but didnt worked, and now I have no idea what to change in code to make it work. I search for ansers but couldnt find any, thats why im writing here, dont hate me pls :(

  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Dec 15 '21 at 00:41

1 Answers1

0

Edit: I noticed your test inherits your class under test Calculator. Don't do that! Instead, create a private Calculator field in your Test class and instantiate it in the setUp() method of the test.

Also, don't pass a file name to your Calculator. Instead, pass an InputStream, so that you can load it from a file, from the network, from a string or even from the terminal.

Do not use a constructor in your class, use a @Before setUp() method instead.

First, this is how I would load test data from a file (if I have to):

  • if possible, paste it directly in a string inside the test.
  • if not feasible, create a test resource file under src/test/resources, for example name it src/test.txt. But remember, this is slow! Then load the resource like this in your test:
public class CalculatorTest {
    private Calculator calculator;

    @Before
    void setUp() throws IOException {
        try {
            InputStream in = getContextClassLoader().getResourceAsStream("src/file.txt");
            calculator = new Calculator(in);
            ...

Tests should be self contained, you should not be passing parameters from the outside.

If you need some kind of configuration, you can use system properties like so:

Properties props = System.getProperties();
props.setProperty("my.path", "/tmp/mytest");

Or you can define them in your pom.xml as explained here:

<property>
      <jvm.options>-Dmy.path=/tmp/mytest</jvm.options>
</property>

[...]
<build>
  [...]
  <plugins>
    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-compiler-plugin</artifactId>
       <configuration>
         <compilerArgs>
              <arg>${jvm.options}</arg>
         </compilerArgs>
      </configuration>
    </plugin>

    <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-surefire-plugin</artifactId>
       <configuration>
            <argLine>${jvm.options}</argLine>
       </configuration>
     </plugin>
   </plugins>
   [...]
</build>
[...]

Also, the tests are not run via your main() method, that's why you cannot pass parameters from there. JUnit has its own main class and method.

D-FENS
  • 1,438
  • 8
  • 21
  • Then how can i edit this variables through getters ? Can u write one Test to show how its is done :) ? –  Dec 08 '21 at 20:20
  • I strongly dislike passing variables to the tests from the outside. Tests should be completely independent from the environment in which they run. Here are some [basic principles](https://medium.com/@tasdikrahman/f-i-r-s-t-principles-of-testing-1a497acda8d6). For this reason I do not pass parameters from the outside and cannot give an example. – D-FENS Dec 08 '21 at 20:25
  • Furthermore, if you **have** to use files in your test (which is a slow operation and breaks the "fast" rule), at least make it self contained - the file should be generated by your test in a dedicated directory, and wiped clean after the test is done. This is a source of trouble though, because if anything goes wrong with the file system (and it will), your test will fail and you will be staying late on a Friday night to fix it. :) – D-FENS Dec 08 '21 at 20:28
  • Instead of using files, dump your test data in a test resource file (a file under `src/test/resources`) and load it via `getResourceAsStream()`. This is the clean way (but it is still slow). – D-FENS Dec 08 '21 at 20:29
  • Please use more recent versions of the plugins in your pom examples because those given are pretty old... (https://maven.apache.org/plugins/) – khmarbaise Dec 08 '21 at 20:47
  • I removed the version numbers. Even if I used the current ones, after a while they still will become obsolete. – D-FENS Dec 08 '21 at 21:42