Search code examples
javatestingjunitmockitofacade

Testing Facades in MVC | Assert Return Type


So in a MVC project, I have Facades, which use Services to get informations.

So what I want to ensure with my tests, is that the right Service-methods for getting the information get called and I want to check if the return type of my facade-method is what I expect.

Of course when I expect a List of Users for example I could just mock one, then use when().thenReturn() to return the List and assert, that the output is th same

The thing is, that I find it annoying to mock everything. Here would be an example for a Method in a Facade:

public List<UserData> getUsersByRegion(final RegionModel userRegion)
    {
        final List<UserModel> userModels = userService.getUsersByRegion(userRegion);
        final List<UserData> userFacadeData = new ArrayList<UserData>();

        for (final userModel model : userModels)
        {
            final UserData userData = new UserData(model.getEmail());
            userFacadeData.add(userData);
        }
        return userFacadeData;
    }

I am new to testing, and what I have understood so far, is that you test something without knowing the implementation. So as a tester I wouldn't know, how the person does it, all I know is, that he needs to use the Userservice and that I want a List with UserData. So I don't know, that he uses model.getEmail() to call the constructor UserData().

Also for example the UserService I don't need to test, since I would write an extra Test for that.

So if I now want to really test what the method does with all the data, I need to mock UserModels, UserData, RegionModels to make an asssertEquals and use when().thenReturn().

And the thing is, that this is a rather short method. Since Facades are there to abstract the complexity of getting and transforming the information, you have a lot of going on in them. So when I have bigger methods I would have so much to mock.

So is this really necessary, is there something I am not thinking about, or how do I approach this? And if I mock, isn't it wise to use when().thenReturn() for the UserService for example, instead of just letting the UserService return itself, since it may happen, that the UserService may have a bug?

P.S.: What would be a way in JUnit/Mockito to test the returntype of a method?

Thanks!


Solution

  • I think you are mocking more things then you actually need. For the example method, you would only need to mock the userService instance. As far as the return type checking, I don't think you should really test it, as Java is a type - safe language. If, by some chance, you return a different type then expected, you will get an exception for sure - most probably even during compilation. A test for your example method should look something like this:

    @Test
    public void testGetUsersByRegion() {
        final UserModel userModel = new UserModel(); // initialise this with all the data you need
        final List<UserModel> userModels = Collections.singletonList(userModel);
        final UserService userService = mock(UserService.class);
    
        doReturn(userModels).when(userService).getUsersByRegion(any(RegionModel.class));
    
        final UserData userData = new UserData(userModel.getEmail());
        final List<UserData> expectedResult = Collections.singletonList(userData);
    
        // this assumes you have an instance of your facade and you have injected the mock user service to it
        final List<UserData> actualResult = usersFacade.getUsersByRegion(testRegion);
    
        verify(userService).getUsersByRegion(eq(testRegion));
        assertEquals(expectedResult, actualResult);
    }