This Week in Dev

Java, HackerRank and PowerMock

I completed the 30 days challenges on HackerRank! HackerRank seems to employ an intentionally convoluted Input scheme, given that they use STATIC classes and instantiate Scanner class as FINAL, but i did manage to create JUnit tests for all the exercises that function equivalently to the online tests. I would be happy to share these (the tests) with others who appreciate the expediency and more robust debugging capabilities of haxoring in their local environment.

I used a tool called PowerMock to get around JUnit’s incapacity for testing static classes, so these unit tests are able to transparently run unmodified code from HR. Ask me for the repo (it just includes my tests and the intermediate code templates they provide for each exercise).

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import static org.junit.Assert.assertEquals;

@RunWith(MockitoJUnitRunner.class)
@PrepareForTest({Solution.class})
public class SolutionTest {

    // a stream to record the output of our program
    private ByteArrayOutputStream testOutput;

    // run before each test (prepare for input / output)
    @Before
    public void setUpOutputStream() {
        testOutput = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOutput));
    }

private void setInput(String input) { System.setIn( new ByteArrayInputStream( input.getBytes() ) ); }

    @Test
    public void test0() {
        final String input = new String(
            "12\n" +
                    "4.0\n" +
                    "is the best place to learn and practice coding!"
        );
        setInput(input);

        final String expected = new String(
            "16\n" +
                    "8.0\n" +
                    "HackerRank is the best place to learn and practice coding!"
        );

        // run the program with no input arguments
        Solution.main(new String[0]);

        // get the output
        final String actual = testOutput.toString().trim();

        // test for equivalence
        assertEquals(expected, actual);
    }

    @Test
    public void test1() {
        final String input = new String(
            "3\n" +
                    "2.8\n" +
                    "is my favorite platform!"
        );
        setInput(input);

        final String expected = new String(
            "7\n" +
                    "6.8\n" +
                    "HackerRank is my favorite platform!"
        );

        // run the program with no input arguments
        Solution.main(new String[0]);

        // get the output
        final String actual = testOutput.toString().trim();

        // test for equivalence
        assertEquals(expected, actual);
    }
}