Reputation: 5075
I have one interface with multiple classes implementation. I have registered them in Autofac Container. My PaymentService class takes two parameters where one of them can implement multiple classes. How to mock to specific class??
Interface
public interface IAccountDataStorage
{
Account GetAccount(string accountNumber);
void UpdateAccount(Account account);
}
Implemented classes
public class BackupAccountDataStore : IAccountDataStorage
{
...
}
public class AccountDataStore : IAccountDataStorage
{
...
}
Register in Autofac container
builder.RegisterType<AccountDataStore>().Keyed("defaultAccountStorage", typeof(IAccountDataStorage));
builder.RegisterType<BackupAccountDataStore>().Keyed("backupAccountStorage", typeof(IAccountDataStorage));
To Resolve Interface of the specific class
var a = buildContainer.ResolveKeyed<IAccountDataStorage>("defaultAccountStorage");
var b = buildContainer.ResolveKeyed<IAccountDataStorage>("backupAccountStorage");
Test class
public class MakePaymentTest
{
private readonly PaymentService sut;
private readonly Mock<IAppAmbientState> mockAppAmbientState = new Mock<IAppAmbientState>();
//private readonly Mock<IAccountDataStorage> mockAccountDataStorage = new Mock<IAccountDataStorage>();
public MakePaymentTest()
{
mockAppAmbientState.Object.AppSettingsRepository = new App.SharedKernel.Values.AppConfiguration
{
DataStoreType = "Backup"
};
//Need help here
sut = new PaymentService(mockAppAmbientState.Object, ???????); // let say I want mock AccountDataStore here...
}
[Fact]
public void MakePayment_Should_ReturnTypeOf_MakePaymentResult()
{
//Arrange
var fixture = new Fixture();
var mockMakePaymentRequest = fixture.Create<MakePaymentRequest>();
//Act
var actualDataResult = sut.MakePayment(mockMakePaymentRequest);
//Assert
}
Upvotes: 0
Views: 1031
Reputation: 26362
You do not Mock a specific implementation. You mock return values
sut = new PaymentService(mockAppAmbientState.Object, ???????); // let say I want mock AccountDataStore here...
What you must do, is make the first and second mock objects, return the proper values for your unit test to follow the needed code paths.
The concrete implementations of the classes, will be tested in their own classes.
The whole idea of the following line, is to use the abstraction and handle the return values. So any link to the actual concrete implementation, beats the point of mocking in the first place.
private readonly Mock<IAccountDataStorage> mockAccountDataStorage = new Mock<IAccountDataStorage>();
Upvotes: 2