注意:mockito 1.10.19
场景如下:;我有一个抽象类:
/**
*
* @param <M> metadata class
*/
@ParametersAreNonnullByDefault
public abstract class AttributeWriter<M>
implements AttributeWriterByName
{
protected final MetadataDriver<M> driver;
protected final Path path;
protected AttributeWriter(final Path path, final MetadataDriver<M> driver)
{
this.driver = driver;
this.path = path;
}
}
AttributeWriterByName
接口非常简单:
@ParametersAreNonnullByDefault
public interface AttributeWriterByName
{
void setAttributeByName(String name, Object value)
throws IOException;
}
一个实现的例子是(最简单的):
@SuppressWarnings("DesignForExtension")
@ParametersAreNonnullByDefault
public abstract class FileOwnerAttributeWriter<M>
extends AttributeWriter<M>
{
protected FileOwnerAttributeWriter(final Path path,
final MetadataDriver<M> driver)
{
super(path, driver);
}
@Override
public void setAttributeByName(final String name, final Object value)
throws IOException
{
if (!"owner".equals(Objects.requireNonNull(name)))
throw new NoSuchAttributeException(name);
setOwner((UserPrincipal) Objects.requireNonNull(value));
}
@SuppressWarnings("MethodMayBeStatic")
public void setOwner(final UserPrincipal owner)
throws IOException
{
throw new ReadOnlyAttributeException();
}
}
匹配的测试文件依赖于一个抽象类,该类如下所示:
public abstract class AttributeWriterTest<W extends AttributeWriter<Object>>
{
protected final Path path = mock(Path.class);
@SuppressWarnings("unchecked")
protected MetadataDriver<Object> driver = mock(MetadataDriver.class);
protected W writer;
protected static FileTime nullFileTime()
{
return isNull(FileTime.class);
}
@BeforeMethod
public abstract void init()
throws IOException;
}
至于实际的测试类,它是:
public final class FileOwnerAttributeWriterTest
extends AttributeWriterTest<FileOwnerAttributeWriter<Object>>
{
@BeforeMethod
@Override
public void init()
throws IOException
{
writer = spy(new FileOwnerAttributeWriter<Object>(path, driver)
{
});
doNothing().when(writer).setOwner(any(UserPrincipal.class));
}
@Test
public void setOwnerTest()
throws IOException
{
final UserPrincipal owner = mock(UserPrincipal.class);
writer.setAttributeByName("owner", owner);
verify(writer).setOwner(same(owner));
}
}
现在,我遇到的问题如下:我基本上想检查在调用.setAttributeName()
之后,除了.setOwner()
之外,没有其他事情发生。
但是,如果我添加到我想要verifyNoMoreInteractions(writer)
的测试中,这将失败,因为在同一测试中,我调用.setAttributeByName()
。。。
尽管这很可能是我的设计中的一个问题(我仍在试验),但有没有一种方法可以让mockito在这样的测试中忽略对setAttributeByName()
的调用,这样我就可以写这个了?
verify(writer, only()).setOwner(same(owner));
EDIT我想写的东西,或者如果它已经存在的话,是这样的:
@Test
public void setOwnerTest()
throws IOException
{
final UserPrincipal owner = mock(UserPrincipal.class);
ignoreInvocation(writer).setAttributeByName("owner", owner);
verify(writer, only()).setOwner(same(owner));
}
我找到了一种方法,请参阅下面的简化示例。总之,您可以在触发对real方法的调用之前重置mock。
我回答这个问题是为了练习Mockito,但我希望很明显,你几乎肯定不应该这样做。
public class SimplifiedExample {
class ClassUnderTest {
public void doSomething(String value) {
doSomethingElse(value);
}
public void doSomethingElse(String value) {
System.out.println(value);
}
}
@Test
public void testMethod() throws Exception {
ClassUnderTest foo = spy(new ClassUnderTest());
final String input = "bar";
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
reset(foo);
invocation.callRealMethod();
return null;
}
}).when(foo).doSomething(anyString());
foo.doSomething(input);
verify(foo, only()).doSomethingElse(input);
}
}