【问题标题】:PowerMockito thenReturn returns wrong objectPowerMockito thenReturn 返回错误的对象
【发布时间】:2014-07-14 15:19:56
【问题描述】:

我正在使用 PowerMockito 在我的测试中模拟静态缓存。 一般来说,缓存是这样工作的:

Cache.getInstance().findEntityById(AbstractDTO);
// so, if I want a TypeA, I use:
TypeADTo typeADTO = // go the dto from the db ...
TypeA = Cache.getInstance().findEntityById(typeADTO);

静态缓存在应用程序中被广泛使用。所以要在单元测试中使用它,我使用:

    PowerMockito.mockStatic( Cache.class );
    final Cache mockedCache = PowerMockito.mock( Cache.class );
    PowerMockito.when( Cache.getInstance() ).thenReturn( mockedCache );
// mock all I want to get
  TypeA typeA = new TypeA(some parameters);
  TypeB typeB = new TypeB(some parameters);

PowerMockito.when(
        Cache.getInstance().findEntityByBusinessId(
                Mockito.any( TypeADTO.class ) ) ).thenReturn( typeA );
PowerMockito.when(
        Cache.getInstance().findEntityByBusinessId(
                Mockito.any( TypeADTO.class ), Mockito.anyBoolean() ) )
        .thenReturn( typeA );


PowerMockito.when(
        Cache.getInstance().findEntityByBusinessId(
                Mockito.any( TypeBDTO.class ) ) ).thenReturn(
        tybeB );
PowerMockito.when(
        Cache.getInstance().findEntityByBusinessId(
                Mockito.any( TypeBDTO.class ), Mockito.anyBoolean() ) )
        .thenReturn( typeB );

我为所有需要的类型创建了一些模拟语句。 (如您所见,一种类型需要模拟不止一种方法)

问题是:power mockito 总是返回在最后一个 PowerMockito.when(...) 语句中设置的对象。

【问题讨论】:

    标签: java unit-testing mockito powermock


    【解决方案1】:

    您是否尝试过链接调用?另外,您可以使用 Mockito 的 when 词。

    Mockito.when(Cache.getInstance().findEntityByBusinessId(any(TypeBDTO.class),anyBoolean()))
           .thenReturn( typeA )
           .thenReturn( typeB );
    

    这将完全按照该顺序记录模拟。

    一个完整的例子供将来参考:

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({BusinessUtility.class})
    public class BusinessUtilityTest {
    
        @Before
        public void setUp() {
            PowerMockito.mockStatic(BusinessUtility.class);
        }
    
        @Test
        public void testStatic() {
            when(BusinessUtility.getDate())
                             .thenReturn(new Date(1111))
                             .thenReturn(new Date(2222));
    
            assertThat(BusinessUtility.getDate()).hasTime(1111);
            assertThat(BusinessUtility.getDate()).hasTime(2222);
        }
    }
    

    提示:

    • 使用静态导入使您的代码更具可读性
    • 仅使用 PowerMockito 来初始化您的静态类,然后继续始终如一地使用 Mockito
    • 尽可能避免使用静态类,测试更难,正如您所见 ;)

    编辑 ----------------------------------

    看看这个例子,与您当前的用例类似:

    类:

    static class BusinessUtility {
        public static <T> T getObject(T instance) {
            return null;
        }
    
        public static <T> T getObject(T instance, Boolean b) {
            return null;
        }
    }
    

    测试:

    @Test
    public void testStatic() {
        //arrange
        when(BusinessUtility.getObject(anyString()))
                .thenReturn("one")
                .thenReturn("two");
    
        when(BusinessUtility.getObject(any(Date.class), anyBoolean()))
                .thenReturn(new Date(1111))
                .thenReturn(new Date(2222));
    
        //act
        String firstStr = BusinessUtility.getObject("asdf");
        String secondStr = BusinessUtility.getObject("qwerty");
    
        Date firstDate = BusinessUtility.getObject(new Date(), true);
        Date secondDate = BusinessUtility.getObject(new Date(), false);
    
        //assert
        assertThat(firstStr).isEqualTo("one");
        assertThat(secondStr).isEqualTo("two");
    
        assertThat(firstDate).isEqualTo(new Date(1111));
        assertThat(secondDate).isEqualTo(new Date(2222));
    }
    

    【讨论】:

    • 假设它们都是相同的类型。 A和b是不同的时间,所以给b adto.class我想要a,bdto.class我想要b等等(+1反正:) l
    • @verbose-mode 请检查编辑,不要忘记检查它是否已解决:)
    猜你喜欢
    • 1970-01-01
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    相关资源
    最近更新 更多