0

Let say I have a class like so

Class A{
   private K Obj = (K)(AppContext.getSpringContext().getBean("obj"))
   
  public void method1{
     // uses Obj
  }

  public void method2{
    // uses Obj
  }

}

And I need to write junits for method1 and method2 by changing the behavior of Obj in method 1 and method 2. In my junit class I am setting the appcontext as so:

public class AccountInformationManagerTest {

    private CCBSAppContext appContext;

    @Mock
    ApplicationContext springContext;
     
    @Mock
    Object obj;

   @Before
    public void setup() throws Exception {
        appContext = new CCBSAppContext();
        appContext.setApplicationContext(springContext);
        Mockito.when(springContext.getBean("obj")).thenReturn(obj);
    }
}

As you can see, I am setting globally the appcontext. I don't want mock the static calls as I am using jacoco and powermockito doesn't integrate very well with jacoco. The problem here is that appcontext is now a global object which is shared across all methods and I need to modify the behavior of obj as I test the two methods. This will create a concurrency issue. How can I resolve this?

Fernando
  • 381
  • 1
  • 5
  • 20

2 Answers2

1

TBH avoid (K)(AppContext.getSpringContext().getBean("obj")) directly inject dependency or autowire the dependency . Then in its easily testable and add obj to the class via SpringTestUtils or setters.

@Autowired
K obj;

Else you can mock springContext getBean method for every test

@Test
void fun {
     Mockito.when(springContext.getBean(Mockito.eq("obj"))).thenReturn(obj);
     // doSomething
}


@Test
void fun2 {
     Mockito.when(springContext.getBean(Mockito.eq("obj"))).thenReturn(obj2);
     // doSomething2
}
NiksVij
  • 183
  • 1
  • 9
1

Use reflection to set the Obj. Then you can set Obj to be a mocked object.

Here is a SO answer describing how to do it.

Jose Martinez
  • 11,452
  • 7
  • 53
  • 68