Given this system to test:
public class MySut
{
private readonly IHardToMockDependency _hardToMockDependency;
public MySut(IHardToMockDependency hardToMockDependency,
IOtherDependency otherDependency)
{
_hardToMockDependency = hardToMockDependency;
}
public string GetResult()
{
return _hardToMockDependency.GetResult();
}
}
public interface IOtherDependency { }
public interface IHardToMockDependency
{
string GetResult();
}
And this unit test:
internal class FakeHardToMockDependency : IHardToMockDependency
{
private readonly string _result;
public FakeHardToMockDependency(string result)
{
_result = result;
}
public string GetResult()
{
return _result;
}
}
public class MyTests
{
[Fact]
public void GetResultReturnsExpected()
{
string expectedResult = "what I want";
var otherDependencyDummy = new Mock<IOtherDependency>();
var sut = new MySut(new FakeHardToMockDependency(expectedResult),
otherDependencyDummy.Object);
var actualResult = sut.GetResult();
Assert.Equal(expectedResult, actualResult);
}
}
How should I convert it to use AutoFixture.Xunit and AutoFixture.AutoMoq (while still using the manual fake)?
In real-world tests, the manual fake would have a more complex interface and behavior. Note that I want to pass the anonymous variable (the expectedResult string) to the constructor of the manual fake.
There are already some good answers here, but I'd like to suggest a simpler alternative that involves slightly loosening the invariants of the FakeHardToMockDependency class. Make it public, and provide a way to assign the result that is decoupled from the constructor:
public class FakeHardToMockDependency : IHardToMockDependency
{
private string _result;
public FakeHardToMockDependency(string result)
{
_result = result;
}
internal string Result
{
get { return _result; }
set { _result = value; }
}
public string GetResult()
{
return _result;
}
}
Notice that I've added an internal property and removed the readonly
keyword from the field.
This enables you to refactor the original test to this:
[Theory, AutoMoqData]
public void GetResultReturnsExpected_AutoDataVersion(
[Frozen(As = typeof(IHardToMockDependency))]FakeHardToMockDependency fake,
MySut sut)
{
var expected = "what I want";
fake.Result = expected;
var actual = sut.GetResult();
Assert.Equal(expected, actual);
}
For completeness, here's the AutoMoqDataAttribute code:
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(new Fixture().Customize(new AutoMoqCustomization()))
{
}
}