Deferred call and lambda expressions

Source: Internet
Author: User
Tags sendmsg
Background gmock

The current Module Testing Framework in our project uses the catch + gmock method to implement regression testing and piling.

The gmock introduction is available on the official website. Here, we will give a rough description of what gmock can achieve. It can be viewed as follows:

  1. Void (){
  2. ???? If (B ()){
  3. ???????? //...
  4. ????}
  5. ???? Else {
  6. ???????? //...
  7. ????}
  8.  
  9. }

A is the tested function, and B is the pile function.

If gmock is used for testing, we can write the test code as follows:

  1. Test_case (test as normal case ){
  2.  
  3. ???? Expect_call (mockobj, B). Times (1). willonce (Return (true); // mockbatrue
  4.  
  5. ???? A (); //
  6. ???? // Bfailedb shocould be called but not called
  7.  
  8. }

Module test

Therefore, after using gmock, we can easily pile up, but one problem is that we must call the function under test () call function B before (describe how many times B should be called and what kind of behavior B has ). Although there is no problem in Ut (because the UT function is called only once), if it is used in the timing test of the module, it will lead to confusion in the timing.

For example, we have a sequence:

Tester --- msg1 --> B
B call if1
B call if2

Tester --- msg2 --> B
B call if3
B call IF4

If we normally write the test code according to the time sequence, we hope this is the case (program1 ):

  1. Test_start ()
  2.  
  3. Sendmsg (TOB, msg1 );
  4. If1_isexpectedtobecalled (Mock)
  5. If2_isexpectedtobecalled (Mock)
  6.  
  7. Sendmsg (TOB, msg2 );
  8. If3_isexpectedtobecalled (Mock)
  9. If4_isexpectedtobecalled (Mock)
  10.  
  11. Test_end ()

However, since the usage of gmock is determined, we must first write it as follows:

  1. Test_start ()
  2.  
  3. If1_isexpectedtobecalled (Mock)
  4. If2_isexpectedtobecalled (Mock)
  5. Sendmsg (TOB, msg1 );
  6.  
  7. If3_isexpectedtobecalled (Mock)
  8. If4_isexpectedtobecalled (Mock)
  9. Sendmsg (TOB, msg2 );
  10.  
  11. Test_end ()

This is quite awkward with a long time series and a lot of piles. Errors may occur during writing and maintenance.

Problem

Can we provide a way (macro) to write code in sequence like program1,

At the same time, the code is executed in the order of program2? (That is, when writing, it is written according to our normal thinking, And when executing, it is executed in the order required by gmock)

For example, you can write code like this:

  1. Test_start ()
  2.  
  3. Test_step (sendmsg (TOB, msg1 ))
  4. If1_isexpectedtobecalled (Mock)
  5. If2_isexpectedtobecalled (Mock)
  6.  
  7. Test_step (sendmsg (TOB, msg2 ))
  8. If3_isexpectedtobecalled (Mock)
  9. If4_isexpectedtobecalled (Mock)
  10.  
  11. Test_end ()

The actual execution sequence is:

  1. If1_isexpectedtobecalled (Mock)
  2. If2_isexpectedtobecalled (Mock)
  3. Sendmsg (TOB, msg1 );
  4.  
  5. If3_isexpectedtobecalled (Mock)
  6. If4_isexpectedtobecalled (Mock)
  7. Sendmsg (TOB, msg2 );

 

Solution

In the middle, my own tossing process is not described in detail. In fact, we want to implement the calling push effect. In addition, because we know the point at which the call needs to be postponed, it is very easy to think of the "destructor", because the Destructor will be called at the end of the scope. Therefore, if we can store function calls in an object, and then let this object call the previously stored function at the specified point structure, the goal is achieved. The question is how to store "functions. The answer is the function library and lamabda expression provided in C ++ 11. The implementation method is as follows:

  1. Class calllater {
  2. Public:
  3. ???? Calllater (function <void (void)> _ fun): m_fun (_ fun ){
  4.  
  5. ????}
  6.  
  7. ????~ Calllater (){
  8. ???????? M_fun ();
  9. ????}
  10. PRIVATE:
  11. ???? Function <void (void)> m_fun;
  12. };
  13.  
  14.  
  15. # Define test_step (fun )??} {Calllater temp ([] () {fun ;});
  16. # Define test_start ()????? {
  17. # Define test_end ()???????}

It is quite concise and comfortable. That's why I like the "syntactic sugar" in C ++ 11 very much ".

Deferred call and lambda expressions

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.