3

我有以下单元测试:

[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"

为什么它声称从未调用过setter?如果它有帮助的话FileSystemWatcherBase就是一个抽象类。

4

1 回答 1

3

感谢 Eugene,我发现这似乎是 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>创建一个新的。

于 2014-02-23T16:25:06.373 回答