[英]How can I mock multiple instances of a struct?
我有一个要模拟的struct
。 在更复杂的测试中,我需要这个结构的几个实例,每个实例都有自己的行为。 为此,我创建了一个辅助方法。
private MyStruct CreateMock(string toString) {
var mock = Mock.Create<MyStruct>();
Mock.Arrange(() => mock.toString()).Returns(toString);
return mock;
}
当我调试一个多次调用此方法的测试时,似乎为结构的所有实例覆盖了Arrange
调用(或者我使用的是 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 框架版本 4.8.03761
安装版本:企业版
JustMock 2020.1.219.1 Telerik JustMock 扩展。
添加示例:
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 论坛上交叉发布了这个问题
编辑:许可证扩展
我的试用许可证被慷慨地延长了。 我已经更新了答案以反映这一点。
如问题中所述,我交叉发布了问题并在那里得到了答案。
这一切都归结为价值与参考比较。 我假设进行了参考比较,但使用了值比较。 当实际将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;
}
}
使用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();
对于这些类型的场景,您需要使用 Autofixture。 https://github.com/AutoFixture/AutoFixture 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.