I am struggling to Unit test the methods in my web service. All of the methods look at the injected WebServiceContext and pull a userId from that in order to make sure that the user is authorized. I have spent many hours trying to figure out how to mock up the WebServiceContext, but no matter what I try, the context is always null.
My end goal is to be able to return a userId that I specify in my test class so that I can proceed on to test the actual functionality of the rest of the method.
This is a stripped down version of how most of the methods are setup:
@HandlerChain(file = "/handler.xml")
@javax.jws.WebService (...)
public class SoapImpl
{
@Resource
private WebServiceContext context;
public void methodUnderTest()
{
// context is NULL here - throws null pointer
Principal userprincipal = context.getUserPrincipal();
String userId = userprincipal.getName();
// Do some stuff - I want to test this stuff, but can't get here
}
}
This is how I am attempting to mock the context and test
@RunWith(MockitoJUnitRunner.class)
@PrepareForTest(SoapImpl.class)
public class SoapImplTest {
@Mock
WebServiceContext context;
@Mock
Principal userPrincipal;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testCreateOverrideRules() {
SoapImpl testImpl = new SoapImpl();
when(context.getUserPrincipal).thenReturn(userPrincipal);
when(userPrincipal.getName()).thenReturn("testUser");
testImpl.methodUnderTest();
assertEquals(1,1);
}
}
I know about dependency injection and passing the context in through the constructor, but I am not sure that I can do that here, because the context is injected through the @resource annotation. A constructor is never called. I don't fully understand how I would implement that.
Also, WebServiceContext and Principal are interfaces, so they cannot be instantiated, which makes this even more confusing. Can anyone help me out here? How can I mock the WebServiceContext and the Principal so I can get past this part of the method and move on to what I really want to test?
UPDATE I was able to solve the problem by using the @InjectMocks annotation as seen in the code below:
@RunWith(MockitoJUnitRunner.class)
@PrepareForTest(SoapImpl.class)
public class SoapImplTest {
@InjectMocks
private SoapImpl testImpl = new SoapImpl();
@Mock
WebServiceContext context;
@Mock
Principal userPrincipal;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
@Test
public void testCreateOverrideRules() {
when(context.getUserPrincipal).thenReturn(userPrincipal);
when(userPrincipal.getName()).thenReturn("testUser");
testImpl.methodUnderTest();
assertEquals(1,1);
}
}