简体   繁体   English

Mockito的ArgumentCaptor:一种方法名称,两种方法定义(第2部分)

[英]Mockito's ArgumentCaptor: One method name, two method definitions (Part 2)

I asked a similar question yesterday in which I'm using a single method name, but have two different arguments I'm passing along. 昨天我问了一个类似的问题 ,其中我使用的是单个方法名,但是我传递了两个不同的参数。 This one does not involve argument types that share a parent class. 这不涉及共享父类的参数类型。

I am using PowerMockito to return a PrintWrite from a constructor. 我正在使用PowerMockito从构造函数返回PrintWrite。 I need to mock its print methods. 我需要模拟其打印方法。

There are four kinds of print/println calls I am tracking: 我正在跟踪四种print / println调用:

print(long l)
print(java.lang.String s) 
print(char c)
println()

Particularly what I care about is the one that prints a long. 我特别关心的是打印很长的纸。 I have the following setup: 我有以下设置:

Mockito.doNothing().when(fakePrintWriter).println();
Mockito.doNothing().when(fakePrintWriter).print(any(Long.class));
Mockito.doNothing().when(fakePrintWriter).print(any(String.class));
Mockito.doNothing().when(fakePrintWriter).print(any(Character.class));

With the following verifies, which I want to capture certain arguments with: 通过以下验证,我想用以下方法捕获某些参数:

Mockito.verify(fakePrintWriter, Mockito.times(11)).print(outputCaptor.capture());
Mockito.verify(fakePrintWriter, Mockito.times(1)).print(longPrintCaptor.capture());
Mockito.verify(fakePrintWriter, Mockito.times(9)).print(eq(','));
Mockito.verify(fakePrintWriter, Mockito.times(3)).println();

Which slaps me in the face with this: 这让我拍了脸:

Wanted but not invoked:
printWriter.print(<Capturing argument>);

Drilling down by testing a print on a long normally, I discovered that calling print(long l) is actually calling println. 通过在一个long上正常地测试打印来进行深入研究,我发现调用print(long l)实际上是在调用println。 So, I instead changed my long print setup/verify to this: 因此,我改为将长打印设置/验证更改为此:

Mockito.doNothing().when(fakePrintWriter).println(any(Long.class));
...
Mockito.verify(fakePrintWriter, Mockito.times(1)).println(longPrintCaptor.capture());

Which then gives me the resulting conflict with println: 然后,这给了我与println的冲突:

Argument(s) are different! Wanted:
printWriter.println(<Capturing argument>);
...
Actual invocation has different arguments:
printWriter.println();
...

Expected :printWriter.println(<Capturing argument>);
Actual   :printWriter.println();

Like yesterday I am at a loss as to how to resolve this- I considered using a custom Answer to track the string that gets outputted (I want to verify the actual order of the values that are being outputted) but I believe doing so would only result in similar errors. 像昨天一样,我对如何解决此问题一无所知-我考虑过使用自定义Answer来跟踪要输出的字符串(我想验证输出值的实际顺序),但我相信这样做只会导致类似的错误。 Any ideas on what to do? 有什么想法做什么?

Instead of trying to mock the PrintWriter, simply use a real one, that writes to memory, instead of to a File. 无需尝试模拟PrintWriter,只需使用一个真正的写入存储器而不是文件的存储器即可。

ByteArrayOutputStream bytes = new ByteArrayOutputStream();
PrintWriter fakePrintWriter = new PrintWriter(byteArrayOutputStream);

// invoke method on unit under test

assertThat(bytes.toString()).isEqualTo(expectedOutput);

I've tried the ByteArrayOutputStream approach and it seems to be empty when I run bytes.toString() . 我尝试了ByteArrayOutputStream方法,当我运行bytes.toString()时,它似乎是空的。 I've found the following seems to work if you don't mind allowing implementations in your test: 如果您不介意在测试中允许实施,我发现以下方法似乎可行:

StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
...
assertThat(printWriter.getBuffer().toString()).isEqualTo(expectedOutput);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM