Я бы, вероятно, сделал что-то подобное, предполагая, что есть и другие ограничивающие факторы, которые означают, что вы хотите изменить как можно меньше внешних деталей о классе (примечание: я не проверял это, поэтому, возможно, придется немного подправить)
public class ClassIAmTesting
{
//Have a Func to fetch a file manager...
private Func<IFileTransferManager> _filemgr = null;
//Have a property which we'll use in this class to get the File manager
public Func<IFilterTransferManager> GetFileManager
{
get
{
//If we try to use this property for the first time and it's not set,
//then set it to the default implementation.
if (_fileMgr == null)
{
_fileMgr = () => IoC.Get<IFileTransferManager>();
}
return _fileMgr;
}
set
{
//allow setting of the function which returns an IFileTransferManager
if (_fileMgr == null)
{
_fileMgr = value;
}
}
}
//this is the method you ultimately want to test...
public async Task<bool> SomeMethodIAmTesting()
{
//don't do this any more:
//_fileTransferManager = IoC.Get<IFileTransferManager>();
//instead do this.
_fileTransferManager = GetFileManager();
await _fileTransferManager
.UploadFile(connection, file.FullName, destinationPath)
.ConfigureAwait(false);
return true;
}
}
Тогда в вашем тестировании:
Mock<IFileTransferManager> _fileTransferManager = new Mock<IFileTransferManager>();
var cut = new ClassIAmTesting();
//not used Moq for a long time, but think you have to access .Object to get to the
//actual implementation of IFileTransferManager?
cut.GetFileManager = () => _fileTransferManager.Object;
//Do actual tests..
var result = cut.SomeMethodIAmTesting();
//Do assertions...
Я предлагаю этот подход, потому что:
- Он обеспечивает способ переопределения способа, которым класс получает
IFileTransferManager
для тестирования - Он «возвращается» к реализации по умолчанию, если это переопределение не используется, сохраняя исходное поведение - вам вообще не нужно изменять существующие вызовы этого класса из не тестирующего кода
- Он не изменяет конструктор и не добавляет новый, что, как я предполагаю, , является проблемой, поскольку вы не просто внедряете экземпляр IFileTransferManager.
Одним из улучшений может быть создание набора internal
, который не позволил бы другим проектам устанавливать этот метод, а затем его можно было бы открыть с помощью InternalVisibleTo
или аналогичного, но я пытаюсьg, чтобы держать прицел довольно плотно ...