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?
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.
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.
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.
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.
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.
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With