Using Mocking Frameworks for Testing

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Using Mocking Frameworks for Testing

dcrissman
I brought up the question about possibly using a mocking framework and got some mixed opinions. So I thought I might post the topic here for further discussion. Before I go further though, I want to clarify that I feel mocking frameworks should only be used for unit tests and never integration testing. That said, it sounded to me like the largest concern was that mocking might actually increase unit test complexity.

My feeling is that mocking allows the unit test to focus on the block of code being tested in isolation. This eliminates complicating factors like specific implementations of an interface or wiring up complex data structures. I also feel that when used correctly, it can make unit testing simpler. If you are testing a subsystem with many calls that need to be mocked out, then a mock framework may not be the best choice, but if each individual method has isolated unit testing than mocking need only be limited to the test case.

To demonstrate what I mean, I went ahead and implemented a simple unit test twice; one with mocking and the other without. I used Mockito for this demo. Which is easier I suppose is a matter of opinion.

    @Test
    public void testInsert() throws Exception {
        CRUDInsertionResponse response = new RDBMSCRUDController(null).insert(
                new CRUDOperationContext(Operation.INSERT, "foo", new Factory(), new HashSet<String>(){{add("Manager");}}, null){
                    @Override
                    public EntityMetadata getEntityMetadata(String entityName) {
                        return new EntityMetadata("test");
                    }
                },
                new Projection(){
                    @Override
                    public JsonNode toJson() {
                        // TODO Auto-generated method stub
                        return null;
                    }
                });

        assertNotNull(response);
    }

    @Test
    public void testInsert_WithMockito() throws Exception {
        CRUDOperationContext context = mock(CRUDOperationContext.class);
        when(context.getEntityMetadata(anyString())).thenReturn(new EntityMetadata("test"));
        when(context.getCallerRoles()).thenReturn(new HashSet<String>(){{add("Manager");}});

        Projection projection = mock(Projection.class);

        CRUDInsertionResponse response = new RDBMSCRUDController(null).insert(context, projection);

        assertNotNull(response);
    }

}
Reply | Threaded
Open this post in threaded view
|

Re: Using Mocking Frameworks for Testing

jewzaam
Administrator
One area the mock framework would be a benefit is when mocking up an interface, instead of a concrete class.  In the case of the interface you just would define side effects that the individual unit test cares about, not everything about the interface.  Also you define the side effects per unit test (if desired) a bit cleaner than doing overrides.  

Is it possible to setup mock stuff per test class in a @Before method?

On Thu, Nov 6, 2014 at 4:29 PM, dcrissman [via lightblue-dev] <[hidden email]> wrote:
I brought up the question about possibly using a mocking framework and got some mixed opinions. So I thought I might post the topic here for further discussion. Before I go further though, I want to clarify that I feel mocking frameworks should only be used for unit tests and never integration testing. That said, it sounded to me like the largest concern was that mocking might actually increase unit test complexity.

My feeling is that mocking allows the unit test to focus on the block of code being tested in isolation. This eliminates complicating factors like specific implementations of an interface or wiring up complex data structures. I also feel that when used correctly, it can make unit testing simpler. If you are testing a subsystem with many calls that need to be mocked out, then a mock framework may not be the best choice, but if each individual method has isolated unit testing than mocking need only be limited to the test case.

To demonstrate what I mean, I went ahead and implemented a simple unit test twice; one with mocking and the other without. I used Mockito for this demo. Which is easier I suppose is a matter of opinion.

    @Test
    public void testInsert() throws Exception {
        CRUDInsertionResponse response = new RDBMSCRUDController(null).insert(
                new CRUDOperationContext(Operation.INSERT, "foo", new Factory(), new HashSet<String>(){{add("Manager");}}, null){
                    @Override
                    public EntityMetadata getEntityMetadata(String entityName) {
                        return new EntityMetadata("test");
                    }
                },
                new Projection(){
                    @Override
                    public JsonNode toJson() {
                        // TODO Auto-generated method stub
                        return null;
                    }
                });

        assertNotNull(response);
    }

    @Test
    public void testInsert_WithMockito() throws Exception {
        CRUDOperationContext context = mock(CRUDOperationContext.class);
        when(context.getEntityMetadata(anyString())).thenReturn(new EntityMetadata("test"));
        when(context.getCallerRoles()).thenReturn(new HashSet<String>(){{add("Manager");}});

        Projection projection = mock(Projection.class);

        CRUDInsertionResponse response = new RDBMSCRUDController(null).insert(context, projection);

        assertNotNull(response);
    }

}


If you reply to this email, your message will be added to the discussion below:
http://dev.forum.lightblue.io/Using-Mocking-Frameworks-for-Testing-tp210.html
To start a new topic under lightblue-dev, email [hidden email]
To unsubscribe from lightblue-dev, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: Using Mocking Frameworks for Testing

lcestari
If you are referring to mockito framework, you can use @Before/@After. It also have other tools like verify (http://www.baeldung.com/mockito-verify) that you can use to guarantee that a certain mocked method was called.

I think in certain cases mocking classes (not only interfaces) makes sense as you may need that if your target class (class under test) have some dependencies to other classes (rather than interfaces) which would leave you to create another class just to override a method (or more) or just mock it (so everything would be close and it can be easier to maintain)

Luan Cestari | Senior Software Applications Engineer
IT Shared Services
M: +55 11 99602-7887
<img src="http://images.engage.redhat.com/eloquaimages/clients/RedHat/{a8aabf3a-4467-4e37-9bc5-48b1d7b494a2}_LATAM_RedHat.jpg" alt="Red Hat" border="0" data-mce-src="http://images.engage.redhat.com/eloquaimages/clients/RedHat/{a8aabf3a-4467-4e37-9bc5-48b1d7b494a2}_LATAM_RedHat.jpg" data-mce-style="font-family: Arial; font-size: 13px;" style="font-family: Arial; font-size: 13px;">
Better technology. Faster innovation. Powered by community collaboration. 
See how it works at www.redhat.com
 





From: "jewzaam [via lightblue-dev]" <[hidden email]>
To: "lcestari" <[hidden email]>
Sent: Thursday, November 6, 2014 7:34:32 PM
Subject: Re: Using Mocking Frameworks for Testing

One area the mock framework would be a benefit is when mocking up an interface, instead of a concrete class.  In the case of the interface you just would define side effects that the individual unit test cares about, not everything about the interface.  Also you define the side effects per unit test (if desired) a bit cleaner than doing overrides.  

Is it possible to setup mock stuff per test class in a @Before method?

On Thu, Nov 6, 2014 at 4:29 PM, dcrissman [via lightblue-dev] <[hidden email]> wrote:
I brought up the question about possibly using a mocking framework and got some mixed opinions. So I thought I might post the topic here for further discussion. Before I go further though, I want to clarify that I feel mocking frameworks should only be used for unit tests and never integration testing. That said, it sounded to me like the largest concern was that mocking might actually increase unit test complexity.

My feeling is that mocking allows the unit test to focus on the block of code being tested in isolation. This eliminates complicating factors like specific implementations of an interface or wiring up complex data structures. I also feel that when used correctly, it can make unit testing simpler. If you are testing a subsystem with many calls that need to be mocked out, then a mock framework may not be the best choice, but if each individual method has isolated unit testing than mocking need only be limited to the test case.

To demonstrate what I mean, I went ahead and implemented a simple unit test twice; one with mocking and the other without. I used Mockito for this demo. Which is easier I suppose is a matter of opinion.

    @Test
    public void testInsert() throws Exception {
        CRUDInsertionResponse response = new RDBMSCRUDController(null).insert(
                new CRUDOperationContext(Operation.INSERT, "foo", new Factory(), new HashSet<String>(){{add("Manager");}}, null){
                    @Override
                    public EntityMetadata getEntityMetadata(String entityName) {
                        return new EntityMetadata("test");
                    }
                },
                new Projection(){
                    @Override
                    public JsonNode toJson() {
                        // TODO Auto-generated method stub
                        return null;
                    }
                });

        assertNotNull(response);
    }

    @Test
    public void testInsert_WithMockito() throws Exception {
        CRUDOperationContext context = mock(CRUDOperationContext.class);
        when(context.getEntityMetadata(anyString())).thenReturn(new EntityMetadata("test"));
        when(context.getCallerRoles()).thenReturn(new HashSet<String>(){{add("Manager");}});

        Projection projection = mock(Projection.class);

        CRUDInsertionResponse response = new RDBMSCRUDController(null).insert(context, projection);

        assertNotNull(response);
    }

}


If you reply to this email, your message will be added to the discussion below:
http://dev.forum.lightblue.io/Using-Mocking-Frameworks-for-Testing-tp210.html
To start a new topic under lightblue-dev, email [hidden email]
To unsubscribe from lightblue-dev, click here.
NAML




If you reply to this email, your message will be added to the discussion below:
http://dev.forum.lightblue.io/Using-Mocking-Frameworks-for-Testing-tp210p211.html
To start a new topic under lightblue-dev, email [hidden email]
To unsubscribe from lightblue-dev, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: Using Mocking Frameworks for Testing

dcrissman
In reply to this post by jewzaam
> Is it possible to setup mock stuff per test class in a @Before method?

Absolutely. Once you have mocked a Class/Interface, it acts for all intents and purposes just like any other instance of that Class/Interface.

I have also used mocks in DI environments to be able to inject mocks into a test contexts. I have seen things like this used very well and also very poorly. I suspect this is where some of the concerns I mentioned in my initial post came from and I would say there is probably some merit to those concerns in this case. It is definitely the sort of thing that can be used for good or evil.