Использование Moq для установки любого по любой клавише и значению
В конце вопроса:
Используя Moq для установки индексаторов на С#, возникла проблема, что кто-то выделил проблему, которая у меня есть. Но они не нашли решения.
В частности, я пытаюсь использовать общий 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
Ответы
Ответ 1
По моему опыту это никогда не работает, вы не можете использовать It.IsAny в качестве помощника в выражении индексатора. Однако он будет соответствовать, если вы укажете конкретное значение в индексаторе.
Например, работает следующее:
httpSession.SetupSet(x => x["someValue"] = It.IsAny<object>())
.Callback( (string index, object value) => {
var i = index;
var v = value;
stateData[i] = v;
});
Ответ 2
Это то, что я сделал, чтобы проверить прочитанное.
_httpSessionStateBaseMock.VerifySet(x => x["keyname"] = It.IsAny<YourObject>(), Times.Once());
для чтения я просто пошел с
_httpSessionStateBaseMock.Verify(x => x["keyname"],Times.Once());
Ответ 3
Мне это не нравится, но я смог обойти его, используя новый класс inherits.
Затем я переопределяю индексатор и вызываю виртуальный метод, который можно высмеять.
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];
});