2

I realize this question has been asked before here -> How to create a test directory in Intellij 13?

However, the answer is not working for me and I can't figure out why...

Intellij Version:

IntelliJ IDEA 2016.1.4
Build #IC-145.2070, built on August 2, 2016
JRE: 1.8.0_77-b03 x86
JVM: Java HotSpot(TM) Server VM by Oracle Corporation

MyApp.java

package main.java.com.simpleproject;

public class MyApp {
    private int updNum;

    public MyApp(int givenNum){
        this.updNum = givenNum;
    }

    private void updateNumPlusTwo(){
        this.updNum += 2;
    }

    protected int getUpdatedNum(){
        return this.updNum;
    }
}

MyAppTest.java

package test.java.com.simpleproject;

import main.java.com.simpleproject.MyApp;

public class MyAppTest {
    public static void main(String[] args) {
        MyApp app = new MyApp(4);

        app.getUpdatedNum();
        app.updateNumPlusTwo();
    }
}

The package/directory tree:

enter image description here

The Issue:

enter image description here

What I have tried:

enter image description here

Anyone have any idea how to get this to work?

Fiddle Freak
  • 1,923
  • 5
  • 43
  • 83

1 Answers1

2

Your sources directories and packages are wrong.

  1. You have chosen the Maven default sources directories structure of src/main/java for production code, and src/test/java for test code. You should declare both directories as source folders in IntelliJ (Project Structure -> Modules -> select the folders and click on Sources for src/main/java and Tests for src/test/java)

  2. Your packages should be the same: com.simpleproject. The problem is that you have declared 2 different packages (main.java.com.simpleproject and test.java.com.simpleproject) that's why you cannot call a protected method.

  3. It is not possible to call a private method, from the same or different package. You have to use reflection for that. But preferably you should at least put your method protected or package default.

  4. Your test should use JUnit, not a main method. Something like :

    package com.simpleproject;
    
    import static org.assertj.core.api.Assertions.assertThat; 
    
    public class Test {   
    
        @Test
        public void shouldTestMyClass() {
           // Given
           int givenNum = 3;
    
           // When
           MyApp myApp = new MyApp(givenNum);
           myApp.updateNumPlusTwo();
    
           // Then (use AssertJ library for example)
           assertThat(myApp.getUpdatedNum()).isEqualTo(5);
        }
    
    }
    
Kruschenstein
  • 283
  • 4
  • 12
rico
  • 1,843
  • 2
  • 24
  • 41
  • Here are all the problems I see when trying this -> https://i.imgur.com/h50UtZE.png – Fiddle Freak Mar 17 '18 at 18:48
  • What the problem looks like after changing `package main.java.com.simpleproject;` to `package com.simpleproject;` in "MyApp.java" -> https://i.imgur.com/o7das2w.png – Fiddle Freak Mar 17 '18 at 18:51
  • I would also like to add the person got these different directories working using eclipse -> https://coderanch.com/i/3247074/eclipse-test-2.png – Fiddle Freak Mar 17 '18 at 18:56
  • ok. Remove the 'private' modifier for the method updateNumPlusTwo. And you need to import JUnit : Project Structure -> Libraries – rico Mar 17 '18 at 18:57
  • If you don't want to use JUnit, you can try with your main method, there is no need to import anything. – rico Mar 17 '18 at 18:58
  • I'll keep this simple and try the main method for now. Until I can get this working as shown in the eclipse screen shot. Oh wow, it works (for protected) -> https://i.imgur.com/uWwJrE1.png. As for private... if I wanted to test private methods, do I have to write test methods in the same class (or is there a better practice for this)? – Fiddle Freak Mar 17 '18 at 19:01
  • The best practice is to remove the private modifier, in order to make the method accessible from your test class. Google guys from Guava or Android projects use the @VisibleForTesting marker annotation : https://stackoverflow.com/questions/33267820/how-to-use-visiblefortesting-for-pure-junit-tests/33279777 – rico Mar 17 '18 at 19:05
  • I see that private methods can still be called by protected methods (called by testClass in a different directly) as long as the private/protected methods are in the same class as shown -> https://i.imgur.com/5tVvidT.png. However, is understood in universal industry, when writing any private methods, these methods will not be tested directly? – Fiddle Freak Mar 17 '18 at 19:13
  • Yes. Exactly. Private methods will be tested along with other protected, package default or public methods. – rico Mar 17 '18 at 19:26