Как я могу издеваться над несколькими экземплярами структуры? - PullRequest
1 голос
/ 07 апреля 2020

У меня есть struct, который я хочу издеваться. В более сложном тесте мне нужно несколько экземпляров этой структуры, каждый со своим поведением. Чтобы облегчить это, я создал вспомогательный метод.

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

Когда я отлаживаю тест, в котором этот метод вызывается несколько раз, создается впечатление, что вызов Arrange перезаписывается для ВСЕХ экземпляров struct (или, может быть, я использую struct mocking вместо экземпляра mocking?).

Я пробовал:

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

Но безрезультатно. Как получить несколько экземпляров структуры?

Я использую: Microsoft Visual Studio Enterprise 2017 Версия 15.9.17 VisualStudio.15.Release / 15.9.17 + 28307.905 Microsoft. NET Framework Версия 4.8. 03761

Установленная версия: Enterprise

JustMock 2020.1.219.1 Telerik JustMock Extension.

Пример добавления :

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;
        }
    }
}

Редактировать: Крест отправил

Я перекрестно разместил этот вопрос на форуме Telerik JustMock

Редактировать: Лицензия продлена

Моя пробная лицензия была любезно продлена. Я обновил ответ, чтобы отразить это.

Ответы [ 3 ]

1 голос
/ 17 апреля 2020

Как описано в вопросе, я перекрестно опубликовал вопрос и получил там ответ.

Все сводится к значению сравнений с эталонным сравнением. Я предполагал эталонное сравнение, но используется сравнение значений. При фактической передаче id на создание макета, он должен работать.

Для удобства копия предложенного решения 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;
    }
}
0 голосов
/ 17 апреля 2020

Вам необходимо использовать Autofixture для этих типов сценариев ios. https://github.com/AutoFixture/AutoFixture.

0 голосов
/ 15 апреля 2020

Использование InSequence()

Например:

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();
...