java - 第一次使用 mockito

标签 java junit mockito

我以前一直在玩弄 jUnit。现在我想将 Mockito 用于学习目的。

我有一个看起来像这样的 REST WS:

@Path("postservice")
public class PostWebService {

private static final Logger logger = Logger.getLogger(PostWebService.class);

//Inject of the stateless post session bean for persisting purposes
@EJB
private PostServiceInterface postService;

/*Webservice for persisting of posts*/
@POST
@Path("postmessage")
@Produces(MediaType.TEXT_PLAIN)
public String insertPost(
        @FormParam("post") String post,
        @Context HttpServletRequest request
) {
    logger.info("insertPost called");
    try {
        request.setCharacterEncoding("UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    User user = (User) request.getSession().getAttribute("user");
    logger.info("Got user from session.");
    if (user != null) {
        postService.insertPost(post, user);
        return "true";
    } else {
        return "false";
    }
}

下面的测试用例可能是错误的:

@RunWith(MockitoJUnitRunner.class)
public class PostWebServiceTest {

@InjectMocks
PostWebService pws;
@Mock
PostServiceInterface mockedPostService;
@Mock
HttpServletRequest request;
@Mock
User user;
@Mock
HttpSession session;

@Before
public void setUp() throws Exception {
    Logger mockedLogger = mock(Logger.class);
}

@Test
public void testInsertPost() throws Exception {
    PostWebService pws = mock(PostWebService.class);
    String post = "Some post";
    when(pws.insertPost(post, request)).thenReturn("true");
    assertTrue(pws.insertPost(post, request) == "true");
}
}

我遇到了几个错误,我决定“删除”或使该特定部分通过以查看我还有哪些其他错误:

第一个错误:

java.lang.NullPointerException
at se.chas.fakebook.webservices.PostWebService.insertPost(PostWebService.java:41)
at se.chas.fakebook.webservices.PostWebServiceTest.testInsertPost(PostWebServiceTest.java:42)

第41行是:User user = (User) request.getSession().getAttribute("user"); 第42行是:when(pws.insertPost(post, request)).thenReturn("true");

我将用户对象初始化为 null 以查看发生了什么,这次我得到了这个错误:

org.mockito.exceptions.base.MockitoException: 
'setCharacterEncoding' is a *void method* and it *cannot* be stubbed with a *return value*!
 Voids are usually stubbed with Throwables:
doThrow(exception).when(mock).someVoidMethod();

然后我删除了 setCharacterEncoding 方法,测试通过了。为什么之前没有通过?

最佳答案

通过此设置,Mockito 将为 PostWebService 创建一个纯 Java 对象,然后将所有其他模拟连接到其中。

这意味着

when(pws.insertPost(post, request)).thenReturn("true");

实际上会尝试执行 insertPost(),因为 pws 本身不是模拟。 when() 只能安全地用于用 @Mock 注释的字段。一个很好的例子是这一行:

User user = (User) request.getSession().getAttribute("user");

由于您的 request 是一个模拟并且您没有告诉 Mockito 为 getSession() 返回什么,因此这里的测试将因 NPE 而失败。请改用此设置代码:

when(request.getSession()).thenReturn(session);
when(session.getAttribute("user")).thenReturn(user);

assertEquals("true", pws.insertPost(post, request));

关于java - 第一次使用 mockito,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25908914/

相关文章:

java - 为什么允许抽象类 "DocumentBuilderFactory"实例化新实例

java - 查找 WebElements,最佳实践

java - com iplanet ias JAR

java - 多次捕获预期方法调用的参数(EasyMock)

java - 如何告诉assertJsonEquals在比较时忽略一个字段

java - 使用 Mockito 测试 GWTP

java - 如何将 ScrollView 动态添加到动态表行

java - JSP - 连接到数据库

java - 模拟具有私有(private)构造函数的类?

java - 当spy()真实对象时,父类(super class)字段没有被分配任何值