简体   繁体   English

如何模拟结构的多个实例?

[英]How can I mock multiple instances of a struct?

I have a struct that I want to mock.我有一个要模拟的struct In a more complex test I need several instances of this struct, each with it's own behavior.在更复杂的测试中,我需要这个结构的几个实例,每个实例都有自己的行为。 To facilitate this, I've created a helper method.为此,我创建了一个辅助方法。

private MyStruct CreateMock(string toString) {
    var mock = Mock.Create<MyStruct>();
    Mock.Arrange(() => mock.toString()).Returns(toString);
    return mock;
}

When I debug a test where this method is called multiple times, it appears as if the Arrange call is overwritten for ALL instances of the struct (or maybe I am using struct mocking instead of instance mocking?).当我调试一个多次调用此方法的测试时,似乎为结构的所有实例覆盖了Arrange调用(或者我使用的是 struct mocking 而不是实例 mocking?)。

I've tried:我试过了:

mock.Arrange(m => m.toString()).Returns(toString); // Using Helpers assembly, note the lowercase m at the start of the line.

But to no avail.但无济于事。 How can I get multiple instances of a struct?如何获取结构的多个实例?

I'm using: Microsoft Visual Studio Enterprise 2017 Version 15.9.17 VisualStudio.15.Release/15.9.17+28307.905 Microsoft .NET Framework Version 4.8.03761我正在使用:Microsoft Visual Studio Enterprise 2017 版本 15.9.17 VisualStudio.15.Release/15.9.17+28307.905 Microsoft .NET 框架版本 4.8.03761

Installed Version: Enterprise安装版本:企业版

JustMock 2020.1.219.1 Telerik JustMock Extension. JustMock 2020.1.219.1 Telerik JustMock 扩展。

Example added :添加示例

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Telerik.JustMock;
using Telerik.JustMock.Helpers;

namespace JustMockFramework
{
    public struct MyStruct
    {
        public readonly string Id;

        public MyStruct(string id)
        {
            Id = id;
        }

        public new string ToString()
        {
            return "Never read me!";
        }
    }

    [TestClass]
    public class MWE
    {
        [TestMethod]
        public void TestSimpleStruct()
        {
            var simpleTest = new MyStruct("1");

            Assert.AreEqual("Never read me!", simpleTest.ToString());
        }

        [TestMethod]
        public void TestMockOfStruct()
        {
            var mock = Mock.Create<MyStruct>();
            Mock.Arrange(() => mock.ToString()).Returns("Read me!");

            Assert.AreEqual("Read me!", mock.ToString());
        }

        [TestMethod]
        public void TestTwoMocksOfStruct()
        {
            var firstMock = Mock.Create<MyStruct>();
            Mock.Arrange(() => firstMock.ToString()).Returns("Read me!");

            var secondMock = Mock.Create<MyStruct>();
            Mock.Arrange(() => secondMock.ToString()).Returns("Read me too!");

            Assert.AreEqual("Read me!", firstMock.ToString()); // Fails with "Read me too!"
            Assert.AreEqual("Read me too!", secondMock.ToString());
        }

        [TestMethod]
        public void TestTwoMocksOfStructCreatedInHelper()
        {
            var firstMock = CreateMockOfStruct("Read me!");

            var secondMock = CreateMockOfStruct("Read me too!");

            Assert.AreEqual("Read me!", firstMock.ToString()); // Fails with "Read me too!"
            Assert.AreEqual("Read me too!", secondMock.ToString());
        }

        private MyStruct CreateMockOfStruct(string toString)
        {
            var mock = Mock.Create<MyStruct>();
            Mock.Arrange(() => mock.ToString()).Returns(toString);
            return mock;
        }

        [TestMethod]
        public void TestTwoMocksOfStructCreatedInHelperWithHelper()
        {
            var firstMock = CreateMockOfStructWithHelper("Read me!");

            var secondMock = CreateMockOfStructWithHelper("Read me too!");

            Assert.AreEqual("Read me!", firstMock.ToString()); // Fails with "Read me too!"
            Assert.AreEqual("Read me too!", secondMock.ToString());
        }

        private MyStruct CreateMockOfStructWithHelper(string toString)
        {
            var mock = Mock.Create<MyStruct>();
            mock.Arrange((m) => m.ToString()).Returns(toString);
            return mock;
        }
    }
}

Edit: Cross posted编辑:交叉发布

I've cross posted this question on the Telerik JustMock forum我已经在 Telerik JustMock 论坛上交叉发布了这个问题

Edit: License extended编辑:许可证扩展

My trial license was graciously extended.我的试用许可证被慷慨地延长了。 I've updated the answer to reflect this.我已经更新了答案以反映这一点。

As described in the question, I cross posted the question and got an answer there.如问题中所述,我交叉发布了问题并在那里得到了答案。

It all boils down to value VS reference comparisons.这一切都归结为价值与参考比较。 I was assuming a reference comparison but a value comparison is used.我假设进行了参考比较,但使用了值比较。 When actually passing an id to the creation of the mock, it should work.当实际将id传递给模拟的创建时,它应该可以工作。

For convenience a copy of the proposed solution by Telerik.为方便起见,提供 Telerik 提出的解决方案的副本。

public struct MyStruct
{
    public readonly string Id;

    public MyStruct(string id)
    {
        Id = id;
    }

    public override string ToString()
    {
        return "Never read me!";
    }
}

[TestClass]
public class MWE
{
    [TestMethod]
    public void TestSimpleStruct()
    {
        var simpleTest = new MyStruct("1");

        Assert.AreEqual("Never read me!", simpleTest.ToString());
    }

    [TestMethod]
    public void TestMockOfStruct()
    {
        var mock = Mock.Create<MyStruct>("1");
        Mock.Arrange(() => mock.ToString()).Returns("Read me!");

        Assert.AreEqual("Read me!", mock.ToString());
    }

    [TestMethod]
    public void TestTwoMocksOfStruct()
    {
        var firstMock = Mock.Create<MyStruct>("1");
        Mock.Arrange(() => firstMock.ToString()).Returns("Read me!");

        var secondMock = Mock.Create<MyStruct>("2");
        Mock.Arrange(() => secondMock.ToString()).Returns("Read me too!");

        Assert.AreEqual("Read me!", firstMock.ToString()); // Fails with "Read me too!"
        Assert.AreEqual("Read me too!", secondMock.ToString());
    }

    [TestMethod]
    public void TestTwoMocksOfStructCreatedInHelper()
    {
        var firstMock = CreateMockOfStruct("1", "Read me!");
        var secondMock = CreateMockOfStruct("2", "Read me too!");

        Assert.AreEqual("Read me!", firstMock.ToString()); // Fails with "Read me too!"
        Assert.AreEqual("Read me too!", secondMock.ToString());
    }

    private MyStruct CreateMockOfStruct(string id, string toString)
    {
        var mock = Mock.Create<MyStruct>(id);
        Mock.Arrange(() => mock.ToString()).Returns(toString);
        return mock;
    }

    [TestMethod]
    public void TestTwoMocksOfStructCreatedInHelperWithHelper()
    {
        var firstMock = CreateMockOfStructWithHelper("1", "Read me!");
        var secondMock = CreateMockOfStructWithHelper("2", "Read me too!");

        Assert.AreEqual("Read me!", firstMock.ToString()); // Fails with "Read me too!"
        Assert.AreEqual("Read me too!", secondMock.ToString());
    }

    private MyStruct CreateMockOfStructWithHelper(string id, string toString)
    {
        var mock = Mock.Create<MyStruct>(id);
        mock.Arrange((m) => m.ToString()).Returns(toString);
        return mock;
    }
}

Use InSequence()使用InSequence()

eg:例如:

var firstMock = Mock.Create<MyStruct>();
Mock.Arrange(() => firstMock.ToString()).Returns("Read me!").InSequence();

var secondMock = Mock.Create<MyStruct>();
Mock.Arrange(() => secondMock.ToString()).Returns("Read me too!").InSequence();

You need to use Autofixture for these types of scenarios.对于这些类型的场景,您需要使用 Autofixture。 https://github.com/AutoFixture/AutoFixture . https://github.com/AutoFixture/AutoFixture

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以使用最小起订量来模拟未来的实例吗? - Can I use MOQ to mock future instances? 我怎么能模拟HttpPostedFileBase mock - How can i mock HttpPostedFileBase mock 如何为组件测试提供多个数据库实例 - How can I have multiple database instances for component tests 如何在 c# 中的 selenium 中打开多个浏览器实例? - How can I open multiple browser instances in selenium in c#? 可能的回购模式问题或如何从多个模拟实例创建一个模拟实例? - Possible repo pattern question or how to create one mock instance form multiple mock instances? 我怎么能模拟TryValidateModel - How can i mock TryValidateModel 单身 - 我可以创建多个实例 - Singleton - I can create multiple instances 如何模拟返回的模拟对象的方法? - How can I mock a method of a returned mock object? 如何创建统一 class 的实例,以便让 class 的多个实例同时运行而不会相互中断 - How can I create instances of a unity class in order to have multiple instances of the class running simultaneously w/o interrupting each other 当我有一个类的多个实例时,如何获取该类的索引/事件? - How can I get the index/event of a class when I have multiple instances of that class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM