Reputation: 447
I'm new to both unit tests, Autofac and mocks so likely, this is relatively easy, but I'm having a hard time figure it out.
I have this class SystemUnderTest
with one dependency, and two methods GetValueOne
and GetValueTwo
.
public class SystemUnderTest : ISystemUnderTest
{
private readonly IDependency _dependency;
public SystemUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public string GetValueOne()
{
return _dependency.GetValueOne();
}
public string GetValueTwo()
{
return _dependency.GetValueTwo();
}
}
public interface ISystemUnderTest
{
string GetValueOne();
string GetValueTwo();
}
These methods gets data from the dependency.
public class Dependency : IDependency
{
public string GetValueOne()
{
return "get-value-one";
}
public string GetValueTwo()
{
return "get-value-two";
}
}
public interface IDependency
{
string GetValueOne();
string GetValueTwo();
}
I'm trying to fake the data from one of the methods (the "GetValueTwo
") so its returning "expected value"
instead of "get-value-two"
which is what the dependency normally returns.
[Fact]
public async Task Test_SystemUnderTest()
{
using (var mock = AutoMock.GetLoose())
{
// Setup
mock.Mock<IDependency>().Setup(x => x.GetValueTwo()).Returns("expected value");
// Configure
mock.Provide<IDependency, Dependency>();
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.Equal("get-value-one", actual_GetValueOne);
Assert.Equal("expected value", actual_GetValueTwo);
}
}
The first part in my test, the Setup
piece, does not seem to have any effect, and its probably because I'm doing some basic stuff wrong.
Anyone with insights on how to save my day?
Upvotes: 1
Views: 2072
Reputation: 247018
The members of Dependency
implementation would need to have virtual members for them to be able to be overridden when doing a partial mocked.
public class Dependency : IDependency {
public virtual string GetValueOne() {
return "get-value-one";
}
public virtual string GetValueTwo() {
return "get-value-two";
}
}
Then similar to what was suggested in another answer you would instead mock the implementation, making sure to enable it to call base members and only setup the members you need to override.
public void Test_SystemUnderTest() {
using (var mock = AutoMock.GetLoose()) {
// Setup
var dependency = mock.Mock<Dependency>();
dependency.CallBase = true;
dependency.Setup(x => x.GetValueTwo()).Returns("expected value");
// Configure
mock.Provide<IDependency>(dependency.Object);
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.AreEqual("get-value-one", actual_GetValueOne);
Assert.AreEqual("expected value", actual_GetValueTwo);
}
}
The above passes when exercised provided that the members of the implementation that need to be mocked can be overridden (ie virtual
).
Upvotes: 2
Reputation: 3230
Not an expert in writing unit tests, but I'm pretty sure that by using Provide
with two type arguments, you overwrite the Setup
part you did previously. By my understanding, the Provide
method should be used to provide your own mock implementation of target interface, so using both Provide
with two type arguments and Setup
for the same dependency doesn't make sense.
So you can either modify the Dependency
implementation's GetValueTwo
to return "expected value"
and use the rest of your code unmodified, or you can supply the mocked instance to the Provide
method with one type argument, with both of the methods previously setup, like this:
[Fact]
public async Task Test_SystemUnderTest()
{
using (var mock = AutoMock.GetLoose())
{
var mockedDependency = mock.Mock<IDependency>();
// Setup
mockedDependency.Setup(x => x.GetValueOne()).Returns("get-value-one");
mockedDependency.Setup(x => x.GetValueTwo()).Returns("expected value");
// The following line is not even necessary
mock.Provide<IDependency>(mockedDependency.Object);
// Arrange - configure the mock
var sut = mock.Create<SystemUnderTest>();
// Act
var actual_GetValueOne = sut.GetValueOne();
var actual_GetValueTwo = sut.GetValueTwo();
// Assert - assert on the mock
Assert.Equal("get-value-one", actual_GetValueOne);
Assert.Equal("expected value", actual_GetValueTwo);
}
}
Upvotes: 1