Mock and stub

Source: Internet
Author: User

As a basic concept of testing, mock and stub are often encountered in development and testing. I think I have understood these two concepts before, but it seems very difficult to write them down and write them clearly so that people who do not understand them can understand them.
Write down this article to check whether you really understand mock and stub.
1) similarities
Let's take a look at the similarities between the two. It is very clear that both mock and stub can be used to isolate the system (or reduce the granularity into modules and units.
In tests, especially unit tests, we usually focus on the functions and behaviors of the main test objects, especially the secondary objects involved in the main test objects, we only focus on the interaction between the main test object and the secondary test object, such as whether to call, when to call, the called parameters, the number and sequence of calls, and the returned results or exceptions. However, we do not pay attention to the details of how secondary objects execute this call. Therefore, a common technique is to use a mock object or stub object to replace a real secondary object, simulate real scenarios to test the main test objects.
Therefore, mock and stub both Replace the secondary test object by creating their own objects, and then control the behavior of this object according to the test requirements.
2) Differences
1. Class Implementation Method
From the perspective of class implementation, Stub has an explicit class implementation, which can be implemented as a common class (reused by multiple test cases) according to the reuse level of stub class ), internal class (used by multiple test methods in the same test case) and internal Anonymous class (used only for the current test method ). The stub method also has specific implementation, even if it is simple enough to have only one simple return statement.
Mock is different. The mock implementation class usually has the mock toolkit such as easymock and jmock for implicit implementation. The specific mock method behavior is specified through the record method.
Take a mock userservice and userdao as an example. In the simplest example, there is only one query method:
Public interface userservice {
User query (string userid );
}

Public class userserviceimpl implements userservice {
Private userdao;
Public user query (string userid ){
Return userdao. getbyid (userid );
}
// Setter for userdao
}

Public interface userdao {
User getbyid (string userid );
}

To implement the standard of stub, You need to implement a class and implement the method:

Public class userdaostub implements userdao {
Public user getbyid (string ID ){
User user = new user ();
User. set .....
Return user;
}
}


@ Test
Public void testgetbyid (){
Userserviceimpl service = new userserviceimpl ();
Userdao = new userdaostub ();
Service. setuserdao (userdao );

User user = service. Query ("1001 ");
...
}

The implementation of mock. Taking easymock as an example, as long as you specify the mock class and record the expected behavior, the new class is not explicitly constructed:

@ Test
Public void testgetbyid (){
Userdao Dao = easymock. createmock (userdao. Class );
User user = new user ();
User. set .....
Easymock. Round CT (DAO. getbyid ("1001"). andreturn (User );
Easymock. Reply (DAO );

Userserviceimpl service = new userserviceimpl ();
Service. setuserdao (userdao );
User user = service. Query ("1001 ");
...
Easymock. Verify (DAO );
}

The comparison shows that mock is relatively simple to write. You only need to pay attention to the used function, the so-called "just enough ". Stub needs to be more complex and implement logic. Even methods that do not need to be concerned should at least provide empty implementations.
2. Test the readability of the logic
From the code above, we can see that in form, mock is usually used to directly mock classes and define mock methods in the test code. The test code and mock code are usually put together, therefore, the logic of the test code is also easy to see from the code of the test case. Easymock. wrong CT (Dao. getbyid ("1001 ")). andreturn (User); it directly specifies the expectation of the current test case for the dependency of userdao: getbyid needs to be called, and the called parameter should be "1001 ", the call count is 1 (easymock defaults to 1 when the call count is not explicitly specified ).
In the code of stub's test case, only simple userdao = new userdaostub (); constructs statements and services. setuserdao (userdao); when setting the statement, we cannot directly see the expectation of dependency from the code in the test case. We can only enter the query () method of the specific userserviceimpl class, the specific implementation is to call userdao. getbyid (userid), so that you can understand the complete test logic. Therefore, when the test logic is complex, the number of stubs is large, and some stubs need to input some labels such as true and false to define different behaviors, the readability of the test logic will decrease.
3. reusability
Mock is rarely considered for reuse. Every passing mock object follows the "just enough" principle and is generally only applicable to the current test method. Therefore, each test method must implement its own mock logic. Of course, some simple initialization logic can be reused in the same test class.
Stub is usually easier to reuse, especially some common stub, such as JDBC connections. The Spring framework has provided a large number of stub for testing. Unfortunately, the name is incorrect: Spring-Mock!
4. Design and use
Next, we will compare the design and use of mock and stub. here we need to introduce two concepts: Interaction-based and state-based.
Interaction-based and state-based are not described in this article. We strongly recommend Martin Fowler's article "mocks aren't stubs ". The address is http://martinfowler.com/articles/mocksArentStubs.html (PS: When the mock stub keyword is entered in Google for search, the first of the results is this article, to Martin Fowler, to Google ), if you are not good at English, refer to the Chinese translation here: http://www.cnblogs.com/anf/archive/2006/03/27/360248.html.
In summary, Stub is state-based and focuses on input and output. Mock is interaction-based and focuses on the interaction process.
5. expectiation/expectation
This is the most important difference between mock and stub: expectiation/expectation.
For mock, exception is the top priority: we expect the method to be called, the appropriate parameters, the number of calls, and the call sequence between multiple mock. All expectations are prepared in advance and verified as expected during and after the test.
For stub, exception is usually not followed, just like the example of userdaostub given above. There is no code to help judge whether the stub class is called. In theory, although some stub implementations can also add expectiation content by encoding themselves, such as adding a counter and calling + 1 each time, this is rarely done.
6. Summary
Regarding the differences between mock and stub, in Martin Fowler's article "mocks aren't stubs", we will end with the following:
(1) dummy
Objects are passed everywhere, but never used. Generally, they are only used to fill in the parameter list.
(2) fake
There are practical implementations, but there are usually some shortcomings that make it unsuitable for products (memory-based databases are a good example ).
(3) stubs
Calls generated during the test process provide a prepared response, typically not responding to anything outside the plan. Stubs may record the call information. For example, the stub of the Mail Gateway records the messages it sends, or it may only record how much information it sends.
(4) mocks
As we said here: pre-planned objects with various expectations form a detailed description of the calls they expect to accept.
3) degradation and Transformation
In the actual development and testing process, we will find that the boundaries between mock and stub are sometimes vague and there is no strict division method, which leads to ambiguity and confusion in our understanding.
The main reason is that in actual use, we often degrade mock to varying degrees, so that the mock object works to some extent like stub. Taking easymock as an example, we can use anyobject () and ISA (class) Methods to relax the parameter detection, and use atleatonce () and anytimes () to relax the detection of the number of calls, we can use easymock. createcontrol () instead of easymock. createstrictcontrol () to relax the detection of the Call Sequence (or call checkorder (false), we can even use createnicecontrol (),
Createnicemock () is used to create a mock that does not limit the call method and automatically returns a simple value. This is basically the same as stub.
Currently, most mock tools support mock degradation to stub. For example, in easyock, apart from any *** and nicemock listed above, it also provides such tools as andstubanswer (), andstubdelegateto (), andstubreturn (), andstubthrow () and asstub ().

As mentioned above, Stub can also implement some expectiation features by adding code. stub can also be converted to mock theoretically, while the boundary between the two is more vague.

----------

Forward from http://www.blogjava.net/aoxj/archive/2010/08/26/329975.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.