2010-11-14 111 views
7

我遇到了与一个的Mockito问题。 我正在开发一个Web应用程序。在我的测试中,用户管理被嘲笑。 有些情况下,我必须更改由getLoggedInUser()方法返回的用户。重的Mockito,存根方法已经存根与thenthrow

的问题是,我的getLoggedInUser()方法也可以抛出AuthenticationException

所以,当我尝试从没有用户的呼叫切换到一些用户,以

when(userProvider.getLoggedInUser()).thenReturn(user); 

抛出一个异常,如userProvider.getLoggedInUser()已经与thenTrow()

存根是否有任何方式告诉when方法不关心异常?

在此先感谢 - 伊什特万

+0

谢谢你们的答案!总结一下:这很可能是因为我需要重新设计该方法的软件设计不佳。但现在对我来说很简单,测试也看起来很干净。 我做了一些更多的研究,并找到了Mockito.reset(T ... mocks)方法,它为我做了诀窍。 下次我会想出一些更简单的设计:) – Szobi 2010-11-16 10:20:43

回答

2

我对你的问题的第一反应是,这听起来像你试图在一个测试中做太多。

为了便于测试和简单的每个测试应该测试的只有一件事。这与Single Responsibility Principle相同。我经常发现程序员试图在一次测试中测试多件事情,并因此而出现各种各样的问题。因此,您的每个单元测试方法都应遵循以下流程:

  1. 为测试设置单个方案。
  2. 让被测试的类呼叫,触发被测试的代码。
  3. 验证行为。

所以你的情况我希望看到至少两个测试。其中getLoggedInUser()返回一个用户,另一个getLoggedInUser()引发异常。这样你就不会在模拟模拟不同行为时遇到问题。

的第二个想法是春天的心是不是存根。看看使用期望,而不是因为你可以设置一系列的期望。即第一个调用返回一个用户,第二个调用抛出异常,第三个调用返回一个不同的用户,等等。

+1

使用'期望'或链接到文档/教程的例子将不胜感激:) – 2014-12-26 23:13:26

2

这听起来像您可能需要使用自定义的答案。 Here is an example

+0

谢谢javamonkey,这也是一个合理的解决方案,但现在我会坚持使用Mockito.reset()。 – Szobi 2010-11-16 10:24:36

+0

有趣 - 我会给你关于一般问题的+1,以了解我刚才了解的有关重置的信息。我相信你也读过它,所以我不会重复它...好东西:) – javamonkey79 2010-11-16 16:43:38

+0

感谢您的+1 :) – Szobi 2011-08-08 09:33:05

1

是否有任何方式告诉如果方法不关心异常?

要真正回答这个问题:

import static org.hamcrest.Matchers.equalTo; 
import static org.hamcrest.Matchers.is; 
import static org.junit.Assert.assertThat; 
import static org.mockito.ArgumentMatchers.any; 
import static org.powermock.api.mockito.PowerMockito.mock; 
import static org.powermock.api.mockito.PowerMockito.when; 

import org.junit.Test; 
import org.mockito.Mockito; 

import java.util.ArrayList; 

public class MyTest { 

    @Test 
    public void testA() { 

     // setup 
     ArrayList<Object> list = mock(ObjectArrayList.class); 
     when(list.indexOf(any())).thenReturn(6); 
     when(list.indexOf(any())).thenReturn(12); 

     // execute 
     int index = list.indexOf(new Object()); 

     // verify 
     assertThat(index, is(equalTo(12))); 
    } 

    @Test 
    public void testB() { 

     // setup 
     ArrayList<Object> list = mock(ObjectArrayList.class); 
     when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!")); 
     when(list.add(any())).thenReturn(true); 

     // execute 
     list.add(new Object()); 
    } 

    @Test 
    public void testC() { 

     // setup 
     ArrayList<Object> list = mock(ObjectArrayList.class); 
     when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!")); 
     Mockito.reset(list); 
     when(list.add(any())).thenReturn(true); 

     // execute 
     list.add(new Object()); 
    } 

    /** 
    * Exists to work around the fact that mocking an ArrayList<Object> 
    * requires a cast, which causes "unchecked" warnings, that can only be suppressed... 
    */ 
    class ObjectArrayList extends ArrayList<Object> { 

    } 
} 

TestB失败,因为你无法摆脱的断言。TestC显示了如何使用reset方法重置模拟并删除其上的thenThrow命令。

请注意,重置似乎并不总是在我有一些更复杂的例子。我怀疑这可能是因为他们使用PowerMockito.mock而不是Mockito.mock