I am mocking a function call with two arguments. 1. input immutable class object 2. out parameter.
sample code:
Mock<ISample> mockSample = new Mock<ISample>();
SampleClass MyKey = new SampleClass() { prop1 = 1 };
SampleOutput output = new SampleOutput() { prop2 = 2 };
mockSample.setup(s => s.SampleMethod(It.is<SampleKey>(t => t.Equals(MyKey)),
out sampleOut))).Returns(true);
in actual code execution this mocked function return proper value if the key is same as mocked key, However, i am seeing a problem that this mocked function is returning same out value even if key does not match.
Any inputs?
Adding key code:
public class Key
{
public readonly DateTime prop1;
public readonly string prop2;
public Key(DateTime prop1, string prop2)
{
this.prop1 = prop1;
this.prop2 = prop2;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (ReferenceEquals(this, obj))
return true;
Key other = obj as Key;
return this.prop1 == other.prop1 && string.Compare(this.prop2, other.prop2);
}
public override int GetHashCode()
{
return prop1.GetHashCode() ^ prop2.GetHashCode();
}
}
As far as I understood the problem, you need to set up mock on two different behaviors. Please take a look on the example test:
[TestFixture]
public class MoqTests
{
[Test]
public void MoqOutParameter()
{
// Arrange
Mock<ISample> mockSample = new Mock<ISample>();
Key MyKey = new Key(DateTime.Today, "SomeValue");
SampleOutput sampleOut = new SampleOutput() { prop2 = 2 };
mockSample.Setup(s => s.SampleMethod(It.Is<Key>(t => t.Equals(MyKey)),
out sampleOut)).Returns(true);
// Act
SampleOutput out1;
var result1 = mockSample.Object.SampleMethod(new Key(DateTime.Today, "SomeValue"), out out1);
SampleOutput out2;
var result2 = mockSample.Object.SampleMethod(new Key(DateTime.MinValue, "AnotherValue"), out out2);
// Assert
Assert.True(result1);
Assert.AreEqual(out1, sampleOut);
Assert.False(result2);
Assert.Null(out2);
}
}
public class Key
{
public readonly DateTime prop1;
public readonly string prop2;
public Key(DateTime prop1, string prop2)
{
this.prop1 = prop1;
this.prop2 = prop2;
}
public override bool Equals(object obj)
{
if (obj == null)
return false;
if (ReferenceEquals(this, obj))
return true;
Key other = obj as Key;
// was forced to add `== 0` to make it compilable
return this.prop1 == other.prop1 && string.Compare(this.prop2, other.prop2) == 0;
}
public override int GetHashCode()
{
return prop1.GetHashCode() ^ prop2.GetHashCode();
}
}
public class SampleOutput
{
public int prop2 { get; set; }
}
public interface ISample
{
bool SampleMethod(Key key, out SampleOutput sampleOut);
}
UPD: I added classes Key
, SampleOutput
and interface 'ISample', that I used in this example and also sorrounding class of tests. I am using Nunit for launching test, it must not make sence. You can use any unit testing frame work, you want. This example works for me, the test is green. Please try it out and say what differs from your environment. Also note that I have changed the return line in Key.Equals
to make it compilable.
Hope it helps.