Mock non-virtual methods, mocknon-virtual

Source: Internet
Author: User

Mock non-virtual methods, mocknon-virtual

Many class methods in the production code are non-virtual. To remove these non-essential dependencies in Gtest, you can use the mock non-virtual methods using templates method of Gmock to achieve the goal.
Before that, you need to understand a design mode: Dependency Injection and Dependency Injection. Although this concept begins with Java and. net, C ++ code should also follow in object-oriented programming.

Ps: an important concept in software engineering is to focus on Separation (Separation of concern, SoC ). Dependency injection is not an aim. It is a series of tools and means. The ultimate goal is to help us develop loose coupled, maintainable, and testable code and programs. This principle is well-known for interfaces, or abstract programming.

 

The following is an example of how to reconstruct the code to achieve DI.
Original code:

class A{public:  int Funtion1(B& obj) {    //do something    std::string str = “mock non-virtual methods using templates”;     auto rst = obj.Function2(str);    //do something  }}

 

class B{public:    int Funtion2(std::string _str){ puts(_str.c_str()); }}

 

When we implement ut protection for the Function1 method of Class A, we do not care about the execution result of the Function2 method of Class B. How can we mock it at this time (Function2 is non-virtual )?

In the above code structure, the answer is: mock cannot be performed! Unless you change Function2 to virtual or use the following method:
After modification:

emplate <class T1 >class  RefactorA{public:  int Funtion1(T1 & obj) {    //do something    std::string str = “mock non-virtual methods using templates”;    auto rst = obj.Function2(str);    //do something  }}

After reconstruction, class RefactorA becomes a class template, and the dependent Class B is explicitly injected during instantiation. At this time, during UT, you can run the "injection" Class B method Function2 mock. The Code is as follows:
// Mock Function2 in Class B

class  mockB{public:  MOCK_METHOD1(Funtion2, int (std::string ));};

/Perform UT test on Class

Class RefactorA _ UT: public: testing: Test {protected: virtual void SetUp () {} virtual void TearDown () {} RefactorA <mockB> mockObjA; // instantiate the template class}; TEST_F (RefactorA _ UT, Funtion1) {// The expected method funtor2 of Class B is called at least once, the return value is 100, and the parameter is any string mockB mockObjB; EXPECT_CALL (mockObjB, Funtion2 (_)). times (AtLeast (1 )). willOnce (Return (100); auto rst = mockObjA. function1 (mockObjB); // note that the mock object EXPECT_TRUE (rst) is passed in here );}

After the Function2 mock method of Class B is put, the UT focus can be placed on other branches of Function1.

 

Note: After Class A is rewritten as A class template, in the production code, you need to use A real class B object to instantiate the template class. In the test code, you need to use the Class B object of mock to instantiate the template class. They are unrelated, which is essentially different from the virtual functions of the mock interface class.

Appendix:

The following four methods can be used to declare and define a class template method:
① The recommended method is implemented when the method is defined (RefactorA class );
② In addition, declarations are implemented outside the template class, but must be in a file;
③ Write the implementation of the method into the xxx. inl file, and then use # include "xxx. inl" at the end of the template class ";
④ Write the implementation of the method into the xxx. cpp file, but the template class needs to be instantiated at the beginning of the cpp file.



In short, in order to write UT code, you must always remember the "dependency injection" principle.
Welcome to the discussion.

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.