I cannot refactor the code, I must test how it is written. I cannot figure out how to test the if (reader.hasNextLong()) line of code:
public class UnitsConvertor {
// No instances please. All methods are static.
private UnitsConvertor() {
}
public static void main(String[] args) {
    // parses user input, checking both integer and string
    System.out.println("Please Enter the input value followed by the unit:");
    Scanner reader = new Scanner(System.in);
    if (reader.hasNextLong()) {
        long number = reader.nextLong();
        if (reader.hasNext("\\b+(mil|in|inch|ft|foot|feet|yd|yard|mi|mile)\\b+")) {
            String unit = reader.findInLine("\\b+(mil|in|inch|ft|foot|feet|yd|yard|mi|mile)\\b+");
            double mm = toMm(number, unit);
            System.out.println(number + " " + unit + " is:");
            System.out.println(String.format("%f", mm) + " mm");
            System.out.println(String.format("%f", mm / 10) + " cm");
            System.out.println(String.format("%f", mm / 1000) + " m");
            System.out.println(String.format("%f", mm / 1000000) + " km");
        } else if (reader.hasNext("\\b+(mm|millimeter|cm|centimeter|m|meter|km|kilometer)\\b+")) {
            String unit = reader.findInLine("\\b+(mm|millimeter|cm|centimeter|m|meter|km|kilometer)\\b+");
            double mil = toMil(number, unit);
            System.out.println(number + " " + unit + " is:");
            System.out.println(String.format("%.2g", mil) + " mil");
            System.out.println(String.format("%.2g", mil / 1000) + " inch");
            System.out.println(String.format("%.2g", mil / 12000) + " ft");
            System.out.println(String.format("%.2g", mil / 36000) + " yard");
            System.out.println(String.format("%.2g", mil / 63360000) + " mile");
        } else {
            System.out.println("Invalid input");
        }
    } else {
        System.out.println("Invalid input");
    }
    reader.close();
    return;
}
// convert any metric system with unit specified in second parameter to mil
public static double toMil(long metric, String unit) {
    double mm;
    if (unit.matches("\\b+(mm|millimeter)\\b+")) {
        mm = metric;
    } else if (unit.matches("\\b+(cm|centimeter)\\b+")) {
        mm = metric * 10;
    } else if (unit.matches("\\b+(m|meter)\\b+")) {
        mm = metric * 1000;
    } else if (unit.matches("\\b+(km|kilometer)\\b+")) {
        mm = metric * 1000000;
    } else {
        throw new IllegalArgumentException("Bad unit value");
    }
    return mm * 39.3701;
}
// convert any imperial system with unit specified in second parameter to mm
public static double toMm(long imperial, String unit) {
    double mil;
    if (unit.matches("\\b+(in|inch)\\b+")) {
        mil = imperial * 1000;
    } else if (unit.matches("\\b+(ft|foot|feet)\\b+")) {
        mil = imperial * 12000;
    } else if (unit.matches("\\b+(yd|yard)\\b+")) {
        mil = imperial * 36000;
    } else if (unit.matches("\\b+(mi|mile)\\b+")) {
        mil = imperial * 63360000;
    } else if (unit.matches("\\b+mil\\b+")) {
        mil = imperial;
    } else {
        throw new IllegalArgumentException("Illegal unit value.");
    }
    return mil * 0.0254;
}
}
Without the testHasNextLong() I reach 98.2% of code coverage. The only yellow and red highlights from code coverage show that hasNextLong(), the else if (reader.hasNext("\b+(mm|millimeter|cm|centimeter|m|meter|km|kilometer)\b+")), and the 2 "elses" that contain System.out.println("Invalid input"); are not covered. When I add in the hasNextLong test only 10/23 tests are run. Without it 22/22 are run.
Here are all the tests I have written:
class UnitsConvertorTest {
private final InputStream systemIn = System.in;
private final PrintStream systemOut = System.out;
private ByteArrayInputStream testIn;
private ByteArrayOutputStream testOut;
private String userUnitInput;
private Long userValueInput;
/**
 * @throws java.lang.Exception
 */
@BeforeEach
void setUp() throws Exception {
    testOut = new ByteArrayOutputStream();
    System.setOut(new PrintStream(testOut, true));
}
/**
 * @throws java.lang.Exception
 */
@AfterEach
void tearDown() throws Exception {
     System.setIn(systemIn);
     System.setOut(systemOut);
}
@Test
public void testHasNextLong() {
  final String testString = "10 mil";
      System.setIn(new ByteArrayInputStream(testString.getBytes()));
      Scanner scanner = new Scanner(systemIn);
      System.out.println("" + scanner.hasNextLong());
      assertTrue(scanner.hasNextLong());
      scanner.close();
      System.setIn(systemIn);
  }
// we have a long and a string
// test when string = mm
@Test
void mmTest() {
    userUnitInput = "mm";
    userValueInput = (long) 10;
    assertEquals(393.701, UnitsConvertor.toMil(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = millimeter
@Test
void millimeterTest() {
    userUnitInput = "millimeter";
    userValueInput = (long) 10;
    assertEquals(393.701, UnitsConvertor.toMil(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = cm
@Test
void cmTest() {
    userUnitInput = "cm";
    userValueInput = (long) 10;
    assertEquals(3937.01, UnitsConvertor.toMil(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = centimeter
@Test
void centimeterTest() {
    userUnitInput = "centimeter";
    userValueInput = (long) 10;
    assertEquals(3937.01, UnitsConvertor.toMil(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = m
@Test
void mTest() {
    userUnitInput = "m";
    userValueInput = (long) 10;
    assertEquals(393701, UnitsConvertor.toMil(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = meter
@Test
void meterTest() {
    userUnitInput = "meter";
    userValueInput = (long) 10;
    assertEquals(393701, UnitsConvertor.toMil(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = km
@Test
void kmTest() {
    userUnitInput = "km";
    userValueInput = (long) 10;
    assertEquals(393701000, UnitsConvertor.toMil(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = kilometer
@Test
void kilometerTest() {
    userUnitInput = "kilometer";
    userValueInput = (long) 10;
    assertEquals(393701000, UnitsConvertor.toMil(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = in
@Test
void inTest() {
    userUnitInput = "in";
    userValueInput = (long) 10;
    assertEquals(254, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = inch
@Test
void inchTest() {
    userUnitInput = "inch";
    userValueInput = (long) 10;
    assertEquals(254, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = ft
@Test
void ftTest() {
    userUnitInput = "ft";
    userValueInput = (long) 10;
    assertEquals(3048, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = foot
@Test
void footTest() {
    userUnitInput = "foot";
    userValueInput = (long) 10;
    assertEquals(3048, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = feet
@Test
void feetTest() {
    userUnitInput = "feet";
    userValueInput = (long) 10;
    assertEquals(3048, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = yd
@Test
void ydTest() {
    userUnitInput = "yd";
    userValueInput = (long) 10;
    assertEquals(9144, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = yard
@Test
void yardTest() {
    userUnitInput = "yard";
    userValueInput = (long) 10;
    assertEquals(9144, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = mi
@Test
void miTest() {
    userUnitInput = "mi";
    userValueInput = (long) 10;
    assertEquals(16093440, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = mile
@Test
void mileTest() {
    userUnitInput = "mile";
    userValueInput = (long) 10;
    assertEquals(16093440, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// we have a long and a string
// test when string = mil
@Test
void milTest() {
    userUnitInput = "mil";
    userValueInput = (long) 10;
    assertEquals(.254, UnitsConvertor.toMm(userValueInput, userUnitInput));
}
// Testing IllegalArgumentException when a user enters a decimal value
@Test
void testExpectedExceptionToMil() {
    Assertions.assertThrows(IllegalArgumentException.class, () -> {
        UnitsConvertor.toMil(10, "mizx");
    });
}
@Test
void testExpectedExceptionToMm() {
    Assertions.assertThrows(IllegalArgumentException.class, () -> {
        UnitsConvertor.toMm(10, "mike");
    });
}
// normalizeExpectedOutput - generate the eol character at run-time. // then
// there is no need to hard-code "\r\n" or "\n" for eol
// and string comparisons are portable between Windows, macOS, Linux.
public String normalizeExpectedOutput(String expectedOutput) {
    String normExpectedOutput;
    String[] outputs = expectedOutput.split("\n");
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    for (String str : outputs) {
        pw.println(str);
    }
    pw.close();
    normExpectedOutput = sw.toString();
    return normExpectedOutput;
}
@Test
// test that user input returns calculation conversions correctly
public void testMainToMm() {
    String inputValueAndUnit = "10 mil";
    Long inputValue = 10L;
    // save current System.in and System.out
    InputStream myIn = new ByteArrayInputStream(inputValueAndUnit.getBytes());
    System.setIn(myIn);
    double mm = UnitsConvertor.toMm(inputValue, "mil");
    final String unNormalizedExpectedOutput = "Please Enter the input value followed by the unit:\n"
            + inputValueAndUnit + " is:\n" + String.format("%f", mm) + " mm\n" + String.format("%f", mm / 10)
            + " cm\n" + String.format("%f", mm / 1000) + " m\n" + String.format("%f", mm / 1000000) + " km";
    final String expectedOutput = normalizeExpectedOutput(unNormalizedExpectedOutput);
    UnitsConvertor.main(null);
    // Check results
    final String printResult = testOut.toString();
    assertEquals(expectedOutput, printResult);
}
@Test
// get invalid number
public void testMainToMil() {
    String inputValueAndUnit = "10 mm";
    Long inputValue = 10L;
    // save current System.in and System.out
    InputStream myIn = new ByteArrayInputStream(inputValueAndUnit.getBytes());
    System.setIn(myIn);
    double mil = UnitsConvertor.toMil(inputValue, "mm");
    final String unNormalizedExpectedOutput = "Please Enter the input value followed by the unit:\n"
            + inputValueAndUnit + " is:\n" + String.format("%.2g", mil) + " mil\n"
            + String.format("%.2g", mil / 1000) + " inch\n" + String.format("%.2g", mil / 12000) + " ft\n"
            + String.format("%.2g", mil / 36000) + " yard\n" + String.format("%.2g", mil / 63360000) + " mile";
    final String expectedOutput = normalizeExpectedOutput(unNormalizedExpectedOutput);
    UnitsConvertor.main(null);
    // Check results
    final String printResult = testOut.toString();
    assertEquals(expectedOutput, printResult);
}
}