Почему moq утверждает, что метод установки свойств моего макета никогда не вызывается, даже если код вызывает его?
У меня есть следующий юнит-тест:
[TestClass]
public class DirectoryWatcherTests
{
private AutoMoqer _mocker;
private DirectoryWatcher _instance;
[TestInitialize]
public void Setup()
{
_mocker = new AutoMoqer();
_instance = _mocker.Create<DirectoryWatcher>();
}
[TestMethod]
public void Watcher_Gets_Path_Set_Same_As_Begin_Path_Parameter()
{
const string path = @"C:\test";
_instance.Begin(path);
_mocker.GetMock<FileSystemWatcherBase>()
.VerifySet(x => x.Path = path);
}
}
Код, который я написал, чтобы это передать:
public class DirectoryWatcher
{
private readonly FileSystemWatcherBase _fileSystemWatcher;
public DirectoryWatcher(FileSystemWatcherBase fileSystemWatcher)
{
_fileSystemWatcher = fileSystemWatcher;
}
public void Begin(string path)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentException("FileSystemWatcher passed in without a valid path already set");
_fileSystemWatcher.Path = path;
}
}
Тем не менее VerifySet
не удается с:
Ожидаемый вызов на макет хотя бы один раз, но так и не был выполнен: x => x.Path = "C:\test"
Почему он утверждает, что сеттер никогда не вызывается? Если это поможет вообще FileSystemWatcherBase
это абстрактный класс.
1 ответ
Благодаря Евгению я понял, что это проблема с Automoq и его совместимостью с последней версией Unity. Я создал следующие тесты, чтобы доказать, что это проблема Automoq, а не проблема Moq:
[TestMethod]
public void Test()
{
const string path = @"C:\test";
var watcherMock = new Mock<FileSystemWatcherBase>();
watcherMock.Object.Path = path;
watcherMock.VerifySet(x => x.Path = path);
}
[TestMethod]
public void Test2()
{
const string path = @"C:\test";
var mocker = new AutoMoqer();
var instance = mocker.Create<Tester>();
var watcherMock = mocker.GetMock<AbstractTest>();
watcherMock.Object.Path = path;
watcherMock.VerifySet(x => x.Path = path);
}
[TestMethod]
public void Test3()
{
const string path = @"C:\test";
var mocker = new AutoMoqer();
var instance = mocker.Create<Tester>();
var watcherMock = mocker.GetMock<AbstractTest>();
instance.Run(path);
watcherMock.VerifySet(x => x.Path = path);
}
[TestMethod]
public void Test4()
{
const string path = @"C:\test";
var testMock = _mocker.GetMock<AbstractTest>();
var tester = new Tester(testMock.Object);
tester.Run(path);
testMock.VerifySet(x => x.Path = path);
}
public abstract class AbstractTest
{
public abstract string Path { get; set; }
}
public class Tester
{
private readonly AbstractTest _test;
public Tester(AbstractTest test)
{
_test = test;
}
public void Run(string path)
{
_test.Path = path;
}
}
Тесты 1, 2 и 4 проходят, а 3 - не пройдены. Мне удалось найти решение этой проблемы с помощью следующего теста:
[TestMethod]
public void Test5()
{
const string path = @"C:\test";
var mocker = new AutoMoqer();
var watcherMock = mocker.GetMock<AbstractTest>();
var instance = mocker.Create<Tester>();
instance.Run(path);
watcherMock.VerifySet(x => x.Path = path);
}
По сути, наличие Automoq поможет мне до создания класса, который я пытаюсь протестировать, позволяет проверке работать. Это наводит меня на мысль, что Automoq не понимает, что moq уже был создан для тестируемого класса, и, следовательно, вызов GetMock<T>
создает новый.