1

I am trying to execute the below code. My IDE tells me

USER_ROLE_EMPLOYEE cannot be resolved to a variable

Here is my code:

public class TestUserHelper {

    @Before
    public void setUp() throws Exception {
        String USER_ROLE_EMPLOYEE="Service Desk";
        String USER_ROLE_MANAGER="Store Manager";
    }

    @Test
    public void testIsUserRoleValidEmployee() {
        Assert.assertTrue(UserValidator.validateSupervisor(USER_ROLE_EMPLOYEE));
    }

    @Test
    public void testIsUserRoleValidSupervisor() {
        Assert.assertTrue(UserValidator.validateSupervisor(USER_ROLE_MANAGER));
    }
}

I am getting an error saying USER_ROLE_EMPLOYEE, USER_ROLE_MANAGER cannot be resolved to a variable.

What am I doing wrong?

O.O.Balance
  • 2,930
  • 5
  • 23
  • 35
Deepboy
  • 523
  • 3
  • 16
  • 28
  • The variables are **local** variables of the setUp() method. So they are only visible inside that method. When asking about an error: **always** read, and post, the exact and complete error message – JB Nizet Jun 19 '18 at 17:59
  • Thankyou JB. Do you know what the fix is? Is there anyway I can still keep the @Before and remove the error? – Deepboy Jun 19 '18 at 18:01
  • The variables need to be **instance** variables. https://stackoverflow.com/questions/16686488/java-what-is-an-instance-variable. Or, since they are actually constants, be static final variables. – JB Nizet Jun 19 '18 at 18:04

3 Answers3

1

Java has different types of variables:

  • There are local variables. These are declared inside of a method and can only be accessed from within that same method. We say these variables have local scope. Your USER_ROLE_EMPLOYEE and USER_ROLE_MANAGER variables are local variables. Thus, accessing them from a method other than the one they were declared in is not possible.
  • There are instance variables. These exist separately within each instance of your class and can be accessed from any non-static method inside your class. As opposed to local variables, they may also be accessible from outside your class; however an instance of the class is always required. You declare them just like local variables, except that you put the declaration outside of any method (directly in your class). They should go at the top. You should add an access modifier (like private) to them, read more about that here.
  • And then there are class variables (static variables). Unlike instance variables, these exist just once and are accessible from any method within your class (even static ones). Declare class variables in the same place as instance variables, but using the static keyword. Like instance variables, these will be accessible from outside of your class depending on the access modifier you declared. Unlike instance variables, they will not require an instance of your class.

So, in your code you can:

  1. Use instance variables instead of local variables:

    public class TestUserHelper {
    
        private String USER_ROLE_EMPLOYEE, USER_ROLE_MANAGER;
    
        @Before
        public void setUp() throws Exception {
            USER_ROLE_EMPLOYEE = "Service Desk";
            USER_ROLE_MANAGER = "Store Manager";
        }
    
        @Test
        public void testIsUserRoleValidEmployee() {
            Assert.assertTrue(UserValidator.validateSupervisor(USER_ROLE_EMPLOYEE));
        }
    
        @Test
        public void testIsUserRoleValidSupervisor() {
            Assert.assertTrue(UserValidator.validateSupervisor(USER_ROLE_MANAGER));
        }
    }
    
  2. Or, and I would recommend this second approach, as your variables are really constants: Declare them as static (class variables) and final (constants). You will not be able to initialize them in setUp() any more, but seeing as they are constant, that is not a problem:

    public class TestUserHelper {
    
        private static final String USER_ROLE_EMPLOYEE = "Service Desk";
        private static final String USER_ROLE_MANAGER = "Store Manager";
    
        @Test
        public void testIsUserRoleValidEmployee() {
            Assert.assertTrue(UserValidator.validateSupervisor(USER_ROLE_EMPLOYEE));
        }
    
        @Test
        public void testIsUserRoleValidSupervisor() {
            Assert.assertTrue(UserValidator.validateSupervisor(USER_ROLE_MANAGER));
        }
    }
    
O.O.Balance
  • 2,930
  • 5
  • 23
  • 35
0

Before is a setup method and currently variables are local in method scope only, move it to class as constants, as @JB Nizet mentioned

    private final static String USER_ROLE_EMPLOYEE="Service Desk";
Ori Marko
  • 56,308
  • 23
  • 131
  • 233
0

@O.OBalance's answer is very good, I would add that local variable can be made even more local !

He introduces scopes briefly, I would add to that a more extensive definition of scope : any piece of code between curly braces ({}) is a scope. And local variable are local to the scope. This means that you can have variable available only for a part of a method.

A common example is a loop :

public int test(){
  int a = 1;
  while(a < 10){
    int b = 2;
    a += b;
  }
  if (b = null) {
    System.out.println("See ?");
  }
  {
    str b = "this is a scope";
  }
  if (b = null) {
    System.out.println("And see this too ?");
  }
  return a;
}
  • While this answer clarifies the topic of scope, it doesn't specifically answer the question asked by the OP and should probably be posted as a comment instead. – patrick.elmquist Oct 07 '20 at 07:53
  • It was my intent but I need at least a reputation of 50 to comment, and I don't have it yet :/ If you want, you can put my answer as a comment, and I would delete my answer. – Assombrance Andreson Oct 08 '20 at 13:17