为什么moq声称我的mock的属性setter永远不会被调用,即使代码调用它?

时间:2014-02-22 21:56:09

标签: c# unit-testing moq automoq

我有以下单元测试:

[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 =&gt; x.Path =“C:\ test”

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

1 个答案:

答案 0 :(得分: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>会创建一个新的。