Results 1 to 6 of 6

Thread: Unit Testing with Mocking and Java Config

  1. #1
    Join Date
    Jul 2006
    Posts
    24

    Default 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. #2
    Join Date
    Oct 2010
    Posts
    5

    Default

    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.

  3. #3
    Join Date
    Jul 2006
    Posts
    24

    Default

    Hey Thanks much. That helps considerably. Really appreciate the help.

  4. #4
    Join Date
    Sep 2009
    Location
    Vilnius, Lithuania
    Posts
    118

    Default

    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...
        }
    }

  5. #5
    Join Date
    Oct 2010
    Posts
    5

    Default

    Quote 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.

  6. #6
    Join Date
    Sep 2009
    Location
    Vilnius, Lithuania
    Posts
    118

    Default

    Quote 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.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •