开发者

Is it possible to query against arguments passed to a Mockito mocked object?

开发者 https://www.devze.com 2023-03-15 04:07 出处:网络
I\'m learning Mockito at the moment and one of the things I\'m doing to consolidate my learning is converting an old JUnit test from using a hand rolled mock class to one which uses Mockito mocks inst

I'm learning Mockito at the moment and one of the things I'm doing to consolidate my learning is converting an old JUnit test from using a hand rolled mock class to one which uses Mockito mocks instead. However, I've run into a situation I'm not sure how to handle.

Specifically, my unit under test constructs a String which gets passed to the mocked object as a parameter in a method call on it. I'd like to test that the String is constructed correctly. The challenge is that part of the String is a hash key which is generated internally and changes on every invocation. One solution that would work would be to get the hash generation under my control and inject a dummy generator for test execution. However, this is a fair bit of work.

My old hand rolled mock class would store the arguments passed to it which I could query in my test. This allowed me to query the start and end of the String via the following:

assertTrue(mockFtpClient.getFilePathAndName().startsWith("/data/inbound/XJSLGG."));
assertTrue(mockFtpClient.getFilePathAndName().endsWith(".pdf"));

This was a sufficent enough test for my taste. So my question is, is it possible using Mockito to query or get a hold of the arguments passed to a method so that i can perform something similiar to the above?

UPDATE 24/06/2011: At this point I have excepted Gnon's answer. However, I have since discovered something which works better for 开发者_运维问答me. Namely ArgumentCaptor. Here's how it works:

ArgumentCaptor<String> fileNameArgument = ArgumentCaptor.forClass(String.class);
verify(mockFtpClient).putFileOnServer(fileNameArgument.capture());
assertTrue(fileNameArgument.getValue().startsWith(START_FILE_NAME) &&
           fileNameArgument.getValue().endsWith(END_FILE_NAME));

The javadoc for Mockito state that ArgumentCaptor is generally a better choice when you have a one-off specific argument matching requirement, as I do here.


Basically you need to use argThat() in Mockito, that lets you treat a Hamcrest Matcher as a verification argument. Here is the code you use to make custom assertions about a passed-in argument:

@Test
public void testname() throws Exception {
    HashReceiver receiver = mock(HashReceiver.class);
    receiver.set("hash");
    verify(receiver).set(argThat(new HashMatcher()));
}

class HashMatcher extends BaseMatcher<String> {
    @Override
    public boolean matches(Object item) {
        String hash = (String) item;
        if (hash.startsWith("/data/inbound/XJSLGG.") && hash.endsWith(".pdf"))
            return true;
        return false;
    }
}

// Mocked
class HashReceiver {
    public void set(String hash) {
    }
}

You may be able to use a generic matcher instead, or a combination of generic matchers.


Have a look at the accepted answer to this question mockito-how-to-make-a-method-return-an-argument-that-was-passed-to-it it will show you how to get a hold of the arguments passed to your mock method invocation.

0

精彩评论

暂无评论...
验证码 换一张
取 消