使用Moq设置任意键和值
本文关键字:键和值 任意 设置 Moq 使用 | 更新日期: 2023-09-27 17:58:42
在问题的末尾:使用Moq在C#中设置索引器时,有人强调了我也遇到的一个问题。但他们没有找到解决方案。
具体来说,我尝试使用通用It.IsAny<string>
作为键的匹配器,并通过It.IsAny<object>
设置值。当通过索引访问并设置值时,它永远不会匹配,也不会访问我的回调方法。所以我的单元测试失败了。
var stateTable = new HashTable;
var httpSession = new Mock<HttpSessionStateBase>();
//works via httpSession.Add(key, value);
httpSession.Setup(x => x.Add(It.IsAny<string>(), It.IsAny<object>()))
.Callback((string index, object value) => {
var i = index;
var v = value;
stateData[i] = v;
});
//does not work via httpSession[key] = value;
httpSession.SetupSet(x => x[It.IsAny<string>()] = It.IsAny<object>())
.Callback( (string index, object value) => {
var i = index;
var v = value;
stateData[i] = v;
});
我使用的是Moq 4.0.10827
根据我的经验,这永远不会起作用,您不能在索引器表达式中使用It.IsAny作为匹配器。但是,如果在索引器中放入一个具体值,它就会匹配。例如,以下方法确实有效:
httpSession.SetupSet(x => x["someValue"] = It.IsAny<object>())
.Callback( (string index, object value) => {
var i = index;
var v = value;
stateData[i] = v;
});
这就是我所做的验证读取的操作。
_httpSessionStateBaseMock.VerifySet(x => x["keyname"] = It.IsAny<YourObject>(), Times.Once());
对于阅读,我刚刚选择了
_httpSessionStateBaseMock.Verify(x => x["keyname"],Times.Once());
我不喜欢它,但我可以使用一个新的继承类来解决它。然后我覆盖索引器并调用一个可以模拟的虚拟方法。
public class HttpSessionStateBaseProxy : HttpSessionStateBase
{
public virtual void SetItem(string key, object value)
{
base[key] = value;
}
public override object this[string name]
{
get
{
return base[name];
}
set
{
SetItem (name, value);
}
}
}
嘲讽是由完成的
Mock<HttpSessionStateBaseProxy> Session = new Mock<HttpSessionStateBaseProxy>(MockBehavior.Loose);
Session.CallBase = true;
Session.Setup(x => x.SetItem(It.IsAny<string>(),It.IsAny<object>()))
.Callback<string,object>((string index, object value) =>
{
if (!this.SessionItems.Contains(index)) this.SessionItems.Add(index, value);
else this.SessionItems[index] = value;
});
Session.Setup(s => s[It.IsAny<string>()]).Returns<string>(key =>
{
return this.SessionItems[key];
});