我正在努力对我的网络服务中的方法进行单元测试。所有方法都会查看注入的WebServiceContext并从中提取userId,以确保用户已获得授权。我花了很多时间试图弄清楚如何模拟WebServiceContext,但无论我尝试什么,上下文总是为空。
我的最终目标是能够返回我在测试类中指定的userId,以便我可以继续测试方法其余部分的实际功能。
这是大多数方法设置的简化版本:
@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
}
}
这就是我试图模拟上下文和测试
的方法@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);
}
}
我知道依赖注入并通过构造函数传递上下文,但我不确定我能在这里做到这一点,因为上下文是通过@resource注释注入的。永远不会调用构造函数。我不完全理解我将如何实现它。
此外,WebServiceContext和Principal是接口,因此无法实例化它们,这使得这更加令人困惑。有人可以帮我从这里出去吗?我如何模拟WebServiceContext和Principal,以便我可以通过该方法的这一部分,继续我真正想要测试的内容?
更新 我能够通过使用@InjectMocks注释来解决问题,如下面的代码所示:
@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);
}
}
答案 0 :(得分:0)
1)你应该有一个构造函数或setter来设置你所测试的类中的上下文。如果你不这样做,你会因为这个原因而添加一个。
2)您不需要实例化WebServiceContext或Principal。只需使用Mockito.mock(WebServiceContext.class)和Mockito.mock(Principal.class)为它们创建模拟。然后添加Mockito.when(mockWebServiceContext)..来添加行为。
请记住,如果您正在进行单元测试,则只想测试测试方法中的逻辑,而不测试任何其他方法或集成。这就是您想要WebServiceContext和Principal的模拟实例的原因。你不想进行集成测试(大概)。
答案 1 :(得分:0)
我能够使用@InjectMocks
注释来解决我的问题。这允许我将我的模拟对象注入到类中。以下两个资源有助于解决这个问题: