2014-02-22 47 views
3

我有以下的單元測試:爲什麼moq聲稱我的模擬的屬性setter永遠不會被調用,即使代碼調用它?

[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是一個抽象類。

+1

在我的結尾工作。你可以顯示FileSystemWatcherBase的代碼嗎? – LostInComputer

+0

這很奇怪。 FileSystemWatcherBase的代碼位於https://github.com/tathamoddie/System.IO.Abstractions/blob/master/System.IO.Abstractions/FileSystemWatcherBase.cs – KallDrexx

+1

是的。仍然有效。這裏是我的源代碼:https://dl.dropboxusercontent.com/u/14576915/MoqTest.zip – LostInComputer

回答

3

感謝尤金我發現這似乎是Automoq及其與Unity最新版本兼容的問題。我創建了下面的測試,以證明它是一個Automoq問題,而不是一個起訂量的問題:

[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>創建了一個新的。

+1

事實上,這是Automoq中的一個錯誤,它是由於您的'AbstractTest'是抽象的,如果您刪除了抽象並使'Path'虛擬,那麼'Test3'也會通過。而且這個bug也是你所經歷的,'Automoq'爲absctact構造函數參數創建了兩個mock,你可以在創建'Tester'之前明確地解析'AbstractTest'來阻止這個。 – nemesv

相關問題