簡體   English   中英

Mocking 使用 Moq 的 Fluent 接口

[英]Mocking a Fluent interface using Moq

我在這里查看了有關此主題的許多問題,但似乎沒有一個可以解決我遇到的問題。

我的代碼看起來有點像這樣......

IBaseDataCollector<MyClass> myDataCollector;

myDataCollector = new Mock<IBaseDataCollector<MyClass>>();

systemUnderTest = new Thing(myDataCollector.Object);

在我的Thing class...

var collection = myDataCollector.SomeMethod()
                     .SomeSecondMethod()
                     .GetData();

SomeMethod()SomeSecondMethod()都返回this (即myDataCollector的實例)

當我運行我的測試時,我在調用myDataCollector的地方得到一個NullReferenceException

我嘗試在我的測試設置中添加它...

myDataCollector.Setup(_=> _.SomeMethod()),Returns(myDataCollector.Object);

但這甚至無法編譯,抱怨它“無法解析方法'Returns(IBaseDataCollector)'”

現在,如果我重構我的Thing class 來閱讀......

myDataCollector.SomeMethod();
myDataCollector.SomeSecondMethod()
var collection = myDataCollector.GetData();

我的測試正常執行。

如果是這樣,我只是重構我的代碼並繼續生活,但實際上,我需要在SelectMany調用中調用我的代碼......

var collection = list.SelectMany(_=> myDataCollector.SomeMethod()
                     .SomeSecondMethod(_)
                     .GetData());

同樣,我知道我可以ForEach替換SelectMany並使用對GetData()調用的每次迭代的結果手動填充集合,這樣我就可以擺脫調用的流利元素,但這意味着重構代碼只是為了讓測試工作,這感覺不對。

我應該如何在我的 Mocked 對象上調用Setup()以使我的流利調用工作?

看看下面的測試代碼(我發明了一些細節來填補空白)。 模擬的 object 實例應該可以作為一個值從其自己的方法返回,如圖所示。

    public class UnitTestExample
    {

        [Fact]
        public void UnitTestExample1()
        {
            var myClassInterfaceMock = new Mock<IInterface<MyClass>>();
            var instance = myClassInterfaceMock.Object;
            var myList = new List<MyClass>()
            {
                new MyClass() { Attribute = 1 }
            };

            myClassInterfaceMock.Setup(_ => _.SomeMethod()).Returns(instance);
            myClassInterfaceMock.Setup(_ => _.SomeSecondMethod()).Returns(instance);
            myClassInterfaceMock.Setup(_ => _.GetData()).Returns(myList);

            var myDependentClass = new MyDependentClass(instance);
            var result = myDependentClass.DoTheThing();

            Assert.True(result.Count.Equals(1));
        }
    }

    public interface IInterface<T>
    {
        IInterface<T> SomeMethod();
        IInterface<T> SomeSecondMethod();
        List<T> GetData();
    }

    public class MyClass
    {
        public int Attribute { get; set; }
    }

    public class MyDependentClass
    {
        private readonly IInterface<MyClass> _test;

        public MyDependentClass(IInterface<MyClass> test)
        {
            _test = test;
        }

        public List<MyClass> DoTheThing()
        {
            return _test.SomeMethod().SomeSecondMethod().GetData();
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM