Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
235 views
in Technique[技术] by (71.8m points)

java - When using Mokito, what is the difference between the actual object and the mocked object?

In the program below, I am trying to use mockito with junit in my test case. But I don't see how Mokito is helping to create objects for my test? I don't see anything special here as it seems as if mokito is instantiating the actually object.

   public class TestCase1{

    @Mock 
    MyClass myClass;

    public void setup(){

       MokitoAnnotations.initMoks(this);

       }
       @Test
       public void testAddition(){

         when(myClass.add(2,2)).thenReturn(20);
         assertEquals(4,myClass.add(2,2));
      }
   }

My actual class (MyClass.java)

    public class MyClass{
        public int add(int x, int y){
           return x+y;
        }
    }

Is it mocking an object, the same as injecting(DI) an object? I appreciate your help!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your test doesn't test any of your code. It tests that Mockito works fine.

When I introduce the concept of mocking, I take this example: suppose you build a detonator, and want to test it. You could of course use the detonator with a real bomb, and see if the whole block explodes when you use the detonator. But that isn't very practical. BTW, maybe you don't even have a bomb at your disposal. Maybe your colleague is still building it.

So you use a mock bomb. Note the important point: to test the detonator, you use a mock bomb. Not a mock detonator. What is mocked is the dependency of the class under test. Not the class under test itself.

What is a mock bomb? It's just a fake bomb that doesn't do anything. All it does is allowing to verify if has been asked to explode or not. So your code to test the detonator would be like this:

// create a mock bomb:
Bomb mockBomb = mock(Bomb.class);
// create a real detonator, but tie it to the mock bomb:
Detonator detonator = new Detonator(mockBomb);

// test the detonator. Since it's tied to a mock bomb, the block
// won't explode
detonator.pressTheRedButton();

// check it the mock bomb has been asked to explode, as it should 
// if the detonator works correctly
verify(mockBomb).explode();

Now if the test passes, you know that all the internal circuitry that is used in pressTheRedButton() works fine and eventually tells the bomb to explode. So you know that, when used with a real bomb, the real bomb will be asked to explode as well when pressing the red button.

Now let's come back to the real world: you want to test a service, and this service uses a DAO that needs a database, populated with data, to run fine. To test your service, you can simply mock the DAO, and verify it works fine. The mock DAO can also be used as a stub, i.e. an object that returns what you tell it to return in the test, instead of actually querying the database. That's what you're doing in the code in your question: you're telling the mock MyClass instance that, when add() is called with 2 and 2 as arguments, it should return 4.

This makes the test easier to setup, faster to run, and independant from the actual code of the DAO, which is not what you want to test in the unit test of the service.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...