Why is it so bad to mock classes?

前端 未结 9 1895
一向
一向 2020-12-07 17:57

I recently discussed with a colleague about mocking. He said that mocking classes is very bad and should not be done, only in few cases.

He says that only interfaces

9条回答
  •  孤城傲影
    2020-12-07 18:19

    Edit: Since you have clarified that your colleague meant mock class is bad but mock interface is not, the answer below is outdated. You should refer to this answer.

    I am talking about mock and stub as defined by Martin Fowler, and I assume that's what your colleague meant, too.

    Mocking is bad because it can lead to overspecification of tests. Use stub if possible and avoid mock.

    Here's the diff between mock and stub (from the above article):

    We can then use state verification on the stub like this.

    class OrderStateTester...
      public void testOrderSendsMailIfUnfilled() {
        Order order = new Order(TALISKER, 51);
        MailServiceStub mailer = new MailServiceStub();
        order.setMailer(mailer);
        order.fill(warehouse);
        assertEquals(1, mailer.numberSent());
      }
    

    Of course this is a very simple test - only that a message has been sent. We've not tested it was send to the right person, or with the right contents, but it will do to illustrate the point.

    Using mocks this test would look quite different.

    class OrderInteractionTester...
      public void testOrderSendsMailIfUnfilled() {
        Order order = new Order(TALISKER, 51);
        Mock warehouse = mock(Warehouse.class);
        Mock mailer = mock(MailService.class);
        order.setMailer((MailService) mailer.proxy());
    
        mailer.expects(once()).method("send");
        warehouse.expects(once()).method("hasInventory")
          .withAnyArguments()
          .will(returnValue(false));
    
        order.fill((Warehouse) warehouse.proxy());
      }
    }
    

    In order to use state verification on the stub, I need to make some extra methods on the >stub to help with verification. As a result the stub implements MailService but adds extra >test methods.

提交回复
热议问题