简体   繁体   中英

Getting null when I @Autowired for the interface in Junit Test

I'm writing JUnit test for this method processData - I'm doing @Autowired Cache mycache in Junit, and mocking Cache mycache under my Test method. When I'm doing this mycache = mock(Cache.class) - this returns some object in Junit method but when I invoke my actual method from Junit Cache mycache going as null in Main class. Please find the code below:

What I'm missing here - how to resolve this NullPointer exception issue - why mycache is going as null when actual method triggered from Junit - though I've mocked this object. Any help would be really appreciated. Thank you!

Main.Java

import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Main {

    @Autowired
    Cache mycache;

    public Product processData(String productId) {

    System.out.println("productId value: " +productId);
    System.out.println("mycache value: " +mycache);

        Product product = (Product) mycache.getIfPresent(productId); //getting NullPointer exception here
        if (product != null) {
            return product;
        }
        // do some processing
        return product;
    }
}

MainTest.Java

public class MainTest {
    @Autowired
    Cache mycache;

    @Test
    public void processDataTest() throws Exception {
        Main main = new Main();
        mycache = mock(Cache.class);
        System.out.println("mycache: " + mycache.toString()); // Mock for Cache, hashCode: 3244883
        when(mycache.getIfPresent("9393939")).thenReturn(null);
        Product product = main.processData("9393939");
        assertNotNull(product);
    }
}

Exception Log trace:

mycache: Mock for Cache, hashCode: 3244883
        productId value: 9393939
        mycache value: null

        java.lang.NullPointerException
        at com.test.processData(Main.java:122)
        at com.test.MainTest.processDataTest(MainTest.java:161)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)

If you have @Autowired a class in your test case you are not supposed to mock it. You will need to annotate the Cache field with @Mock or else you would not able to mock the Cache.class.

The reason you are getting null at processData is because the Cache object is autowired and not mocked.

java.lang.NullPointerException
        at com.test.processData(Main.java:122)

Could you please try the below code instead,

public class MainTest {

    @Mock
    Cache mycache;

    @Test
    public void processDataTest() throws Exception {
        Main main = new Main();
        // mycache = mock(Cache.class);
        System.out.println("mycache: " + mycache.toString()); // Mock for Cache, hashCode: 3244883
        when(mycache.getIfPresent("9393939")).thenReturn(null);
        Product product = main.processData("9393939");
        assertNotNull(product);
    }
}

Instead of doing:

@Component
public class Main {

   @Autowired
   Cache mycache;
   ...

Inject it via a constructor:

  @Component
  public class Main {
      private final Cache mycache;

      public Main(Cache mycache) {
          this.mycache = mycache;
      }
  }

Now it your test you can create an instance of Main where you can provide a mock of Cache .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM