Announcement Announcement Module
Collapse
No announcement yet.
Unit Testing with Mocking and Java Config Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Unit Testing with Mocking and Java Config

    I am trying to understand how one would use Mocking with Java Config to substitute the actual object.

    @Configuration
    public class MyConfig {
    @Bean
    public PaymentService paymentService() {
    return new PaymentServiceImpl(auditService());
    }

    @Bean
    public AuditService auditService() {
    return new AuditServiceImpl();
    }
    }

    In my unit test, I am hoping to mock out the AuditService like so:

    class OrderServiceTest {
    private AuditService auditServiceMock;
    private ApplicationContext ctx;

    @Before
    public void setUp() {
    auditServiceMock = Mockito.mock(AuditService.class);
    ctx = new AnnotationApplicationContext(MyConfig.class);

    // What I need to do is ctx.set(auditServiceMock);
    }

    @Test
    public void ordersericeTest() {
    Mockito.when(auditServiceMock.doSomething(..)).the nReturn(somethingElse);

    OrderService s = ctx.get(OrderService.class);
    s...
    }

    How would I tell the Context to use my mock object rather than the actual AuditServiceImpl. I do not want to use XML Config here but JavaConfig.

    Thanks in advance for any help.

  • #2
    Try to use a context like this for your test:

    Code:
    @Configuration
    @Import (MyConfig.class)
    public class MyTestConfig {
    
          @Bean
          public AuditService auditService() {
               return Mockito.mock(AuditService.class);
          }
    }
    This "auditService" bean definition is supposed to overwrite the default one.

    Then within your test class:

    Code:
    class OrderServiceTest {
    
          @Autowired
          private AuditService auditServiceMock;
    
          @Autowired
          private OrderService s;
    
          @Before
          public void setUp() {
                Mockito.when(auditServiceMock.doSomething(..)).thenReturn(somethingElse);
          }
    
          @Test
          public void ordersericeTest() {
    
                s...
          }
    }
    Test class setup depends on which testing framework you're working with.

    Comment


    • #3
      Hey Thanks much. That helps considerably. Really appreciate the help.

      Comment


      • #4
        I'd argue that unit tests should not depend on containers like Spring. Luckily, Spring is all about POJOs, and POJOs are great because they can be tested in isolation. What I mean is if you're writing a true unit test (and mock objects seem to indicate that that's the case), you don't need Spring to run it. Just wire your dependencies manually:

        Code:
        class OrderServiceTest {
        
            private AuditService auditServiceMock;
            private OrderService orderService;
        
            @Before
            public void setUp() {
                auditServiceMock = Mockito.mock(AuditService.class);
                orderService = new OrderService(auditServiceMock);
            }
        
            @Test
            public void ordersericeTest() {
                Mockito.when(auditServiceMock.doSomething(..)).thenReturn(somethingElse);
                orderService...
            }
        }

        Comment


        • #5
          Originally posted by Osvaldas Grigas View Post
          I'd argue that unit tests should not depend on containers like Spring. Luckily, Spring is all about POJOs, and POJOs are great because they can be tested in isolation. What I mean is if you're writing a true unit test (and mock objects seem to indicate that that's the case), you don't need Spring to run it. Just wire your dependencies manually:
          Imho, container frameworks can't/shouldn't say that much about what and how you're doing/testing. Inversion of control is just a pattern and Spring Framework simply helps in such a task. I can't really figure out why having a "new" statement could improve unit testing but it's just me.

          Comment


          • #6
            Originally posted by Caos81 View Post
            I can't really figure out why having a "new" statement could improve unit testing but it's just me.
            That's because unit tests should be as simple as possible, and "new" operator is the simplest thing that could possibly work. It is certainly simpler than doing the same thing in a @Bean method of a separate @Configuration class. In this case, you're not testing the DI itself or any of Spring's AOP interceptors or BeanPostProcessors - you're only testing the OrderService.

            Comment

            Working...
            X