Smocks doesnt support method that takes local reference variables as a parameters.
Karthik-Venkatesalu opened this issue · 3 comments
Mocking a method requires parameter values to be matched.
This works fine for values types and member reference variables.
I came across a situation where my mocked method takes local reference variable as the parameter. And mocking this method does not return the mocked return value.
Something similar to below.
[TestClass]
public class UnitTest2
{
[TestMethod]
public void TestMethod1()
{
Smocks.Smock.Run(context =>
{
object obj = new object();
context.Setup(() => SomeStaticClass.GetId(obj)).Returns(10);
SomeClass sc = new SomeClass();
var id = sc.GetId(); // which doesnt return mocked value '10'
});
}
}
public class SomeClass
{
public int GetId()
{
object obj = new object();
return SomeStaticClass.GetId(obj);
}
}
public class SomeStaticClass
{
public static int GetId(object obj)
{
return 55;
}
}
Can you suggest a solution for this?
This is by design. For reference types, a setup is only matched if the provided argument is the same (ReferenceEquals
).
Consider the following compact version of your example:
public static void TestMethod1()
{
Smocks.Smock.Run(context =>
{
object object1 = new object();
object object2 = new object();
context.Setup(() => SomeStaticClass.GetId(object1)).Returns(10);
Console.WriteLine(SomeStaticClass.GetId(object1)); // Outputs 10
Console.WriteLine(SomeStaticClass.GetId(object2)); // Outputs 55 (default implementation)
});
}
The setup matches object1
but not object2
, as object1
was used in the setup.
This behaviour is identical to Moq's behaviour. This is the same example converted to Moq:
public static void TestMethod2()
{
object object1 = new object();
object object2 = new object();
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.GetId(object1)).Returns(10);
Console.WriteLine(mock.Object.GetId(object1)); // Outputs 10
Console.WriteLine(mock.Object.GetId(object2)); // Outputs 0 (default)
}
Right now, you could try to use It.IsAny<object>()
so that any object
matches the setup. Support for Moq-alike It.Is(obj => ...)
, so that you can specify the conditions used for matching a setup yourself, is on Smock's roadmap.
It solves this issue. Thanks a lot for your quick response.
I have one more issue.
While continuing the testing, method under the test throws "InvalidProgramException - Common Language Runtime detects invaild program" exception.
Calling the same method outside the smock context, works fine.
From my search, I found that this exception occurs when there is mismatch in generated IL.
Just to know, is this problem relates to Smock?
Method which I am testing is an extensive method which has around 2k lines of
code.
Your advice is greatly aprreciated on this.
That is most likely a Smocks issue indeed. In order to fix it, I'll need a minimal code example (preferably < 2k lines) that reproduces the issue. If you can provide such an example, please open a separate issue for that problem with the code sample. I'll close this issue for now.