Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best simple way to mock static/global function?

I have a simple almost value-like class like Person:

class Person
{
public:
    Person(ThirdPartyClass *object);
    virtual ~Person(void);

    virtual std::string GetFullName() const;
    virtual int GetAge() const;
    virtual int GetNumberOfDaysTillBirthday() const;
};

I'm using a third party library and the ThirdPartyClass needs to have a global/static function called Destroy (part of the 3rd party library) called on it to destroy it. This Destroy function is called in the Person destructor.

Now I'm trying to unit test my Person class and I need a way to mock/stub the Destroy method. I think I could write a wrapper class around the static Destroy function and then use dependency injection to inject this wrapper into the Person class, but it seems like overkill to do that just to call this one function on this simple class. What's a simple straightforward way to do this? Or is dependency injection really the best way to do this?

Update

Ultimately I decided to go with creating a class that wrapped all the 3rd party library's global functions and then using dependency injection to pass this class into the constructor of my person class. This way I could stub out the Destroy method. Although the person class only uses a single function, the other functions of the library are called at other points in my code and as I needed to test those I would face the same issue.

I create a single instance of this wrapper class in my main app code and inject it where needed. I chose to go this route because I think it's clearer. I like Billy ONeal's solution and I think it answers my question, but I realized if I were to leave the code for a few months and come back it would take me longer to figure out what was happening as compared to dependency injection. I'm reminded of the zen of python aphorism "Explicit is better than implicit." and I feel dependency injection makes what's happening a bit more explicit.

like image 401
User Avatar asked Jun 30 '11 23:06

User


People also ask

Can you mock static methods?

Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.

How do you mock a static function in jest?

To mock the static method, simply assign jest. fn() to the static method like so: Another scenario is when private constructor is used to instantiate a class (see: When to use a private constructor), the question arises — how do I mock the dependencies?

Can we mock static methods using MOQ?

You can use Moq to mock non-static methods but it cannot be used to mock static methods.

Is static function global?

In C, functions are global by default. The “static” keyword before a function name makes it static. For example, below function fun() is static. Unlike global functions in C, access to static functions is restricted to the file where they are declared.


1 Answers

Create a link seam. Put your destroy declaration in a header, and then have two implementation files:

// Destroy.cpp
void Destroy()
{
    //Code that really does destruction
}

And for testing:

// DestroyFake.cpp
void Destroy()
{
    //Code that does fake destruction
}

Then link the first file to your main binary, and the second file to your testing binary.

Beyond this, what you ask for is impossible. The linker bakes calls to global functions and static methods into direct jumps into the callee code -- there's no lookup or decision process to hook into to create any type of overload like the one you're looking for (beyond having Destroy calling something that's more easily mocked).

like image 73
Billy ONeal Avatar answered Oct 05 '22 00:10

Billy ONeal