Closed zenyuk closed 1 year ago
I checked your example. You should write a test a little bit different. Part that you want to be mocked should be under callback in Mock.Setup
method. I rewrote you example and it works for me:
[Test]
public void Test()
{
// arrange
Mock.Setup(typeof(Callee), nameof(Callee.Call2), () =>
{
// act
var mockActualResult = Caller.Call1(0);
// assert
Assert.AreEqual(11, mockActualResult);
}).Returns(11);
var rollbackedResult = Caller.Call1(0);
// assert rollback
Assert.AreEqual(2, rollbackedResult);
}
thank you for the explanation, basically for my example the original test should be rewritten in the way:
[Test]
public void TestPass()
{
// arrange
Mock.Setup(typeof(Callee), nameof(Callee.Call2), () =>
{
// act
var mockActualResult = Caller.Call1(0);
// assert
Assert.AreEqual(11, mockActualResult);
}).Returns(11);
}
where I should be doing the act
and assert
within the Mock.Setup body only.
And if I need to mock a few calls like Callee.Call2
here executing sequentially, I assume by design I should be placing the whole test method code above inside the second Mock.Setup body. Something like
[Test]
public void TestPass()
{
// arrange
Mock.Setup(typeof(Callee), nameof(Callee.Call2), () =>
{
Mock.Setup(typeof(CalleeNext), nameof(CalleeNext.Call3), () =>
{
// act
var mockActualResult = Caller.Call1(0);
// assert
Assert.AreEqual(26, mockActualResult);
}).Returns(15);
}).Returns(11);
}
// while the method under test is:
public class Caller
{
public static int Call1(int x)
{
x++;
int r = Callee.Call2(x);
r += CalleeNext.Call3(x);
return r;
}
}
Yes, your examples look good and should work. If not, let me know. And this is a good idea to support multiple classes/methods mocking in one setup. I will try to implement this in future versions. Thank you.
What would be good is to support sequential calls instead of hierarchical
existing implementation:
// arrange
Mock.Setup(typeof(Callee), nameof(Callee.Call2), () =>
{
Mock.Setup(typeof(CalleeNext), nameof(CalleeNext.Call3), () =>
{
// act
var mockActualResult = Caller.Call1(0);
// assert
Assert.AreEqual(26, mockActualResult);
}).Returns(15);
}).Returns(11);
to be like:
// arrange
Mock.Setup(typeof(Callee), nameof(Callee.Call2)).Returns(11);
Mock.Setup(typeof(CalleeNext), nameof(CalleeNext.Call3)).Returns(15);
// act
var mockActualResult = Caller.Call1(0);
// assert
Assert.AreEqual(26, mockActualResult);
Thank you for suggestions. Looks like good improvement. I will implement this, but also for compatibility I will leave hierarchical calls too.
looks awesome, thanks for your work
Only what I found is if I change the mocked method to be generic, it fails.
I am using StaticMock.Mock.Setup(Type type, String methodName)
signature
public class Callee
{
public static int Call2<T>(T x)
{
return 11;
}
}
stack trace:
System.ArgumentNullException: Value cannot be null.
Parameter name: GenericTypes
at StaticMock.Helpers.SetupMockHelper.GetOriginalMethodInfo(Type type, String methodName, SetupProperties setupProperties)
at StaticMock.Helpers.SetupMockHelper.SetupInternal(Type type, String methodName, Action action, SetupProperties setupProperties)
at StaticMock.Mock.Setup(Type type, String methodName)
for generic methods mock you should close generic type with SetupProperties
. Here is an example:
Method for test:
public static TEntity GenericTestMethodReturnDefaultWithoutParameters<TEntity>()
{
return default;
}
Mock:
const int expectedResult = 2;
using var _ = Mock.Setup(
typeof(TestStaticClass),
nameof(TestStaticClass.GenericTestMethodReturnDefaultWithoutParameters),
new SetupProperties { GenericTypes = new[] { typeof(int) } })
.Returns(expectedResult);
var actualResult = TestStaticClass.GenericTestMethodReturnDefaultWithoutParameters<int>();
Assert.AreEqual(expectedResult, actualResult);
Here a link for example in tests https://github.com/SvetlovA/static-mock/blob/c9f089d14e0db3b5a52f62b3a79423e7fc05a6da/src/StaticMock.Tests/Tests/Sequential/ReturnsTests/MockReturnsTests.cs#L330
Attached is an example (full project) with the simplest possible test for a scenario when a static method is calling another static method.
Can't make it to mock. The mock is ignored and the original method is executed instead.
StaticMockExample.zip