Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to verify static method call using Moq

Using this approach I have made my static method calls an Action in the hope that I can set and verify the call in my Moq unit test.

The code being tested is:

public Action<Data> Calculate = x => CalculatorHelper.Calculate(x);

public void CalculateData(Data data)
{
    ...

    Calculate(data);

    ...
}

And the test is:

[Test]
public void CalculateIsCalled()
{
    _mockService.Setup(x => x.Calculate = CalculatorHelper.Calculate)
                .Verifiable();
    ...

    _mockService.VerifyAll();
}

However, the parameter in the Setup() is throwing the compile error "an expression tree cannot contain an assignment operator".

Obviously the code x => x.Calculate = CalculatorHelper.Calculate is incorrect but what would the correct way to code this?

like image 251
Digbyswift Avatar asked Jan 17 '13 12:01

Digbyswift


People also ask

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. Although static methods cannot be mocked easily, there are a few ways to mock static methods. You can take advantage of the Moles or Fakes framework from Microsoft to mock static method calls.

Can you unit test static methods?

Use the Extract and Override Call Extract and override call is a refactoring technique that you can use to unit test a static method. The idea is to create a new protected method that will wrap the call to the static method.

How do you write a test case for a static method?

Note that you should add the class that contains static methods in two places in your unit tests: On top of the unit test class using @PrepareForTest annotation. In your test setup by calling the PowerMockito. mockStatic to do the necessary initialization step before trying to mock any of its methods.

How do you mock static class in NSubstitute?

NSubstitute can't mock static methods, so if you want to use NSub for this you'll need to rewrite the original class, or wrap the functionality in a new class that you can mock.


2 Answers

Calculate should return a new Action pointing to CalculatorHelper.Calculate, so it should be:

_mockService.Setup(x => x.Calculate).Returns(CalculatorHelper.Calculate)
            .Verifiable();

However, for this to work, Calculate needs to be a virtual property, not just a field.

like image 92
Daniel Hilgarth Avatar answered Oct 21 '22 11:10

Daniel Hilgarth


Considering the fact that Calculate is public field, you don't even need Moq here (also assuming you are testing that CalculateData calls the delegate):

Data passedAsActionParameter = null;
var testedClass = new Calculator();
testedClass.Calculate = d => { passedAsActionParameter = d; };
var data = new Data();
testedClass.CalculateData(data);

Assert.That(passedAsActionParameter, Is.EqualTo(data));
like image 28
k.m Avatar answered Oct 21 '22 09:10

k.m