Java – mockito style anyxxx unit test method

When unit testing some methods, some situations may occur. The value of some parameters is not important and can be any value

For example, in this Code:

public void method(String arg1,String arg2,int arg3){
    if(arg1 == null) throw new NullPointerException("arg1 is null");

    //some other code
}

When arg1 is null, NPE must be thrown. The values of other parameters are unimportant. They can be any value or empty

So I want to record the fact that these values are irrelevant to the method under test

I thought of the following options:

Option 1: define any_ Constant of XXX

I want to explicitly create the constant any_ String and any_ Int, which contains a fixed value, records that it can be any value, and the measured method does not care about the actual value

I can put all these constants in a class named any and reuse them in all test classes

Option 2: any_ Random value of XXX

This option seems a bit of a hacker to me because I've read somewhere that randomness should not be brought into test cases But in this case, this randomness will not be visible because the parameter will not have any side effects

Which method is more suitable for better, readable testing?

to update:

Although I can use any by defining constants in the any class_ XXX method, but I'm also considering using some constraints to generate any_ XXX value, for example

Any.anyInteger().nonnegative();
Any.anyInteger().negative();

Any.anyString().thatStartsWith("ab");

I think maybe hamcrest matchers can be used to create this link But I don't know if it's good Similar methods of anyobject () have been provided by mockito, but these methods are only applicable to mocks and spies, not ordinary objects I want to implement the same more readability tests for normal objects

Why?

Suppose I have a class

class MyObject{

     public MyObject(int param1,Object param2){
          if(param1 < 0) throw new IllegalArgumentException();
          if(param2 == null) throw new NullPointerException();
     }
}

Now when writing the test constructor

class MyObjectTest{

     @Test(expected=NullPointerException.class)
     public void testConstructor_ShouldThrowNullpointer_IfSecondParamIsNull(){

          //emphasizing the fact that value of first parameter has no relationship with result,for better test readability
          new MyObject(Any.anyInteger().nonnegative(),null);
     }
}

Solution

My preference is to establish a utility class constant and method to help create the constant value of the test, for example:

public final class Values {
    public static final int ANY_INT = randomInt(Integer.MIN_VALUE,Integer.MAX_VALUE);
    public static final int ANY_POSITIVE_INT = randomInt(0,Integer.MAX_VALUE);
    public static final String ANY_ISBN = randomIsbn();
    // etc...

    public static int randomInt(int min,int max) { /* omitted */ }
    public static String randomIsbn() { /* omitted */ }

    // etc...
}

Then I will use static import to pull the constants and methods required by a specific test class

I only use any if I don't care about the value_ Constants, I found that they can make the test intention clearer, for example:

// when
service.fooBar(ANY_INT,ANY_INT,5);

Obviously, a value of 5 has some meaning - although it would be better as a local variable

Utility methods can be used to automatically generate values when setting up tests, for example:

// given
final String isbn1 = randomIsbn();
final String isbn2 = randomIsbn();
final Book[] books = { new Book(isbn1),new Book(isbn2) };

// when
bookRepository.store(books);

Again, this can help test courses care about the test itself rather than about data settings

In addition, I also used similar methods from domain objects When you combine these two methods, it can be very powerful For example:

public final class Domain {
    public static Book book() {
        return new Book(randomIsbn());
    }
    // etc...
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>