PowerMockito.spy在用于验证时会中断测试

时间:2017-02-04 17:57:13

标签: java junit mockito netty powermockito

我有一个测试Netty处理程序的单元测试(下面的简化版本)。

  1. 我使用处理程序的实例创建EmbeddedChannel
  2. 调用者将字符串写入通道
  3. 处理程序接收字符串,反转并将其写回。
  4. 调用者从通道读取返回值,并验证它是否与发送的字符串相反。
  5. 这完美无缺。但是,我需要verify频道上的调用次数,所以我创建了spy频道,但没有嘲笑任何方法,因为我不想改变班级的行为,只计算调用。

    现在测试失败了。其中2个断言成功。它们是确保调用处理程序的测试,以及用于验证调用通道方法的次数的测试。但是,使用间谍时,最终的读取响应始终为null。

    我的印象是,没有其他嘲弄的孤独间谍不会影响间谍物体的行为,但显然它确实如此。 [nonPower] Mockito文档表明复制的对象可能会导致此问题,但PowerMockito文档并不具体。

    我正在使用Netty 4.1.6.Final和Powermock 1.5.6。

    更新:我设法让测试工作,但它有点不稳定的解决方法。请参阅新方法 testSpiedEmbeddedChannel2 。解决方法是使用 ecx 创建非间谍频道( ecx ),然后创建间谍频道( ec )。我发布了 ec 上的写入,并使用 ecx 进行了读取。这意味着如果我尝试验证读取中使用的方法,则不会计算它们。

    这里是成功和失败测试的代码。

    @RunWith(PowerMockRunner.class)
    @PowerMockIgnore({"javax.management.*"})
    @PrepareForTest(EmbeddedChannel.class)
    public class TestEmbeddedChannel {
    
        class EchoHandler extends ChannelDuplexHandler {
            final AtomicInteger reads = new AtomicInteger(0);
            @Override
            public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
                reads.incrementAndGet();
                final String value = (String)msg;
                final String response = new StringBuilder(value).reverse().toString();
                ctx.channel().writeAndFlush(response);
            }
        }
    
        @Test
        public void testEmbeddedChannel() {  // PASSES
            final EchoHandler handler = new EchoHandler();
            final EmbeddedChannel ec = new EmbeddedChannel(handler);
            ec.writeInbound("Hello World");
            final String response = ec.readOutbound();      
            Assert.assertEquals(1, handler.reads.get());
            Assert.assertEquals("dlroW olleH", response);
    
        }
    
        @Test
        public void testSpiedEmbeddedChannel() {  // FAILS
            final EchoHandler handler = new EchoHandler();
            final EmbeddedChannel ec = spy(new EmbeddedChannel(handler));
            ec.writeInbound("Hello World");
            final String response = ec.readOutbound();
            verify(ec, times(2)).isOpen();  // OK
            Assert.assertEquals(1, handler.reads.get());  // OK
            Assert.assertEquals("dlroW olleH", response);  // FAILS
        }
    
        @Test
        public void testSpiedEmbeddedChannel2() {  // PASSES
            final EchoHandler handler = new EchoHandler();
            final EmbeddedChannel ecx = new EmbeddedChannel(handler); 
            final EmbeddedChannel ec = spy(ecx);
            ec.writeInbound("Hello World");
            final String response = ecx.readOutbound(); // Read using non-spied channel
            verify(ec, times(2)).isOpen();
            Assert.assertEquals(1, handler.reads.get());
            Assert.assertEquals("dlroW olleH", response);
        }   
    
    }
    

    感谢您提供任何指导。

0 个答案:

没有答案