[英]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.