gpt4 book ai didi

c# - 我如何使用最小起订量模拟一个集合

转载 作者:可可西里 更新时间:2023-11-01 08:48:29 26 4
gpt4 key购买 nike

我是单元测试和模拟的新手,而且耳后仍然湿漉漉的。我正在使用 Moq 框架,我需要模拟一个集合,以便它生成一个具有我提供的值的成员。

有问题的集合类是 System.Configuration.SettingsPropertyCollection ,其中包含 SettingsProperty对象。

反过来,SettingsProperty有一个 Attributes返回 SettingsAttributeDictionary 的属性.

我需要我的收藏才能产生一个 SettingsProperty ,在其 System.Attribute 中有一个自定义属性(源自 Attributes.SettingsAttributeDictionary) .

我真的在努力解决这个问题,但到目前为止无济于事。我试过伸出舌头并朝它做鬼脸,但没有任何效果。

这是我到目前为止尝试过的代码,在代码中注释的地方抛出异常,所以当然测试总是失败。

    [TestMethod]
public void GetPropertySettings_Should_Return_Default_Values_When_Device_Not_Registered()
{
const string deviceName = "My.UnitTest";
const string deviceType = "Switch";
var deviceId = String.Format("{0}.{1}", deviceName, deviceType);
Mock<IProfile> mockProfile = new Mock<IProfile>();
Mock<SettingsContext> mockSettingsContext = new Mock<SettingsContext>();
// Construct a SettingsPropertyCollection populated with a single property.
// The single property will have a fixed name and default value, and will also have a single
// attribute, giving teh ASCOM DeviceId.
var deviceAttribute = new ASCOM.DeviceIdAttribute(deviceId);
var attributes = new SettingsAttributeDictionary();
attributes.Add(typeof(DeviceIdAttribute), deviceAttribute);
var settingsProperty = new SettingsProperty(SettingName, typeof(string), null, false, SettingDefaultValue, SettingsSerializeAs.String, attributes, true, true);
var propertyCollection = new SettingsPropertyCollection();
propertyCollection.Add(settingsProperty);

// Now comes the interesting part where we call our IProfile - this is where we really need Moq.
// Expectations:
// - mockProfile must have it's DeviceType set.
// - mockProfile's device type (captured in setDeviceType) must match deviceType.
// - The returned SettingsPropertyValueCollection must not be empty.
// - The returned SettingsPropertyValueCollection must have exactly one entry.
// - The entry must match the value of SettingDefaultValue.

// Expectation: IProfile must have its DeviceType set. We capture the value into setDeviceType.
var setDeviceType = String.Empty;
mockProfile.SetupSet(x => x.DeviceType).Callback(y => setDeviceType = y);

// Finally, it is time to call the method we want to test
var settingsProvider = new SettingsProvider(mockProfile.Object);

// THE NEXT LINE THROWS AN EXCEPTION
// IF I TRY TO STEP INTO IT, IT NEVER RETURNS AND THE TEST RUN JUST ENDS.
var result = settingsProvider.GetPropertyValues(mockSettingsContext.Object, propertyCollection);

// Now lets verify that everything went as expected
// First, let's test that the parsing of DeviceId was as expected: IProvider.DeviceType was set to the expected value
Assert.AreEqual(deviceType, setDeviceType);
// Then let's test that the methods of IProvider that we mocked were called
mockProfile.VerifyAll();

// With this done, let's turn to the output of the method
// Firstly, we test that the resulting collection contains exactly one item of the type SettingsPropertyValue
Assert.IsTrue(result.Count > 0);
Assert.AreEqual(1, result.Count);
Assert.IsTrue(result.OfType<SettingsPropertyValue>().Count() > 0);

// Then let's inspect the contained SettingsProviderValue further
var settingsPropertyValue = result.OfType<SettingsPropertyValue>().First();

// First IsDirty flag must never be set
Assert.IsFalse(settingsPropertyValue.IsDirty);

// The PropertyValue must be the default value we passed in
Assert.AreEqual(SettingDefaultValue, settingsPropertyValue.PropertyValue);
}

抛出的异常(由测试运行器报告)是:

Test method ASCOM.Platform.Test.SettingsProviderTest.GetPropertySettings_Should_Return_Default_Values_When_Device_Not_Registered threw exception: System.ArgumentException: The type System.Configuration.SettingsContext implements ISerializable, but failed to provide a deserialization constructor.

最佳答案

我相信您需要设置模拟 SettingsProperty 的 Attributes 属性以返回模拟 SettingsAttributeDictionary 并然后设置模拟 SettingsAttributeDictionary 的索引器以返回所需的值,例如

mockItem.SetupGet(x => x.Attributes).Returns(mockAttributes);

mockAttributes.SetupGet(x => x[It.IsAny<System.Type>()])
.Returns(deviceAttribute);

编辑

在 Moq 使用的 CaSTLe DynamicProxy 类中抛出异常。我相信这与 Moq 如何模拟可序列化的对象有关。如果 caSTLe 在签名为 (SerializationInfo, StreamingContext) 的可序列化对象上找不到非公共(public)构造函数,则会抛出此异常。您可以做的是更改自定义 SettingsProvider 的 GetPropertyValues 方法,以便它接受 Hashtable 而不是 SettingsContext,并向方法调用提供模拟 Hashtable 而不是模拟 SettingsContext。 Hashtable 具有所需的构造函数,因此也许这会起作用。坚持使用类型为 SettingsContext 而不是 Hashtable 的参数并没有真正的优势,因为 SettingsContext 只是简单地从 Hashtable 派生,即它不添加任何成员。

关于c# - 我如何使用最小起订量模拟一个集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2210392/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com