user5417542
user5417542

Reputation: 3376

Mocking public method call inside ClassUnderTest | Deal with ArrayLists

Let's assume I have following scenario:

public class ClassUnderTest()
        {

        private Service myService;

        public SomeData method1(final InputData input) {
            final SomeData result = method2(myservice.getOutput(input));
            return result;
        }

        public SomeData method2(final OutputData output){
            //Do something with the OutputData
        }
   }

Now I want to test method1(). Since it's calling method2() I also need to assure everything inside method2() works fine. But the thing is, since I test all the methods, I would test method2() seperately.

So how do I know only test method1() without considering method2(). I would love to just use doNothing() when method2() get's called, but since it's the class I want to test and not mocked, so I can't do that. Or is there a possibility?

2.) How do I assert the equality of two ArrayList, when they both should just have two Objects with equal values. For example:

@Test 
public void test(){
User user1 = new User();
User user2 = new User();

user1.setMail("mail");
user2.setMail("mail");

list<User> list1 = new ArrayList<User>();
list<User> list2 = new ArrayList<User>();

list1.add(user1);
list2.add(user2);

assertEquals(list1,list2);

}

This would fail, since they are not equal Objects.

Upvotes: 1

Views: 376

Answers (2)

Ruben
Ruben

Reputation: 4056

The first part of your question has already been answered by Mathias. Using PowerMock would be an alternative.

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassUnderTest.class)
public class YourTest {

    @Test
    public void yourTest() {
        PowerMockito.suppress(MemberMatcher.method(ClassUnderTest.class, "method2"));
        ClassUnderTest m = mock(ClassUnderTest.class);
        //method2 will not be called
        m.method1();
    }
}

Regarding the list assertion, you can use of the powerful samePropertyValuesAs matcher in Hamcrest.

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.samePropertyValuesAs;

@Test
public void yourTest() throws Exception {

    ....

    assertThat(list1, containsInAnyOrder(userCollectionToMatcher(list2)));
}

public Collection<Matcher<? super User>> userCollectionToMatcher(Collection<User> users) {
    return users.stream().map(u -> samePropertyValuesAs(u)).collect(Collectors.toList());
}

Upvotes: 0

Mathias Dpunkt
Mathias Dpunkt

Reputation: 12184

You should really ask the questions separately but I try to answer both:

1. Partial Mocks with Mockito

I am not really sure it is really advisable to mock partially. But with mockito it is possible. You could mock your ClassUnderTest and tell mockito to execute the real method when method1 is called

ClassUnderTest mock = Mockito.mock(ClassUnderTest.class);
when(mock.method1()).thenCallRealMethod();

See http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#partial_mocks

2. Assertions on collections

AssertJ gives you very nice assertions on collections - e.g.:

List<String> list1 = Arrays.asList("1", "2", "3");
List<String> list2 = Arrays.asList("1", "2", "3");
then(list1).containsExactlyElementsOf(list2);

see here for details https://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#extracted-method-result-assertion

https://github.com/joel-costigliola/assertj-examples/blob/master/assertions-examples/src/test/java/org/assertj/examples/ListSpecificAssertionsExamples.java

Upvotes: 1

Related Questions