developer tip

인덱스 속성을 MOQ하는 방법

optionbox 2020. 11. 5. 07:56
반응형

인덱스 속성을 MOQ하는 방법


인덱싱 된 속성에 대한 호출을 모의하려고합니다. 즉, 다음을 moq하고 싶습니다.

object result = myDictionaryCollection["SomeKeyValue"];

또한 setter 값

myDictionaryCollection["SomeKeyValue"] = myNewValue;

내 앱에서 사용하는 클래스의 기능을 모의해야하기 때문에이 작업을 수행합니다.

누구든지 MOQ로 이것을 수행하는 방법을 알고 있습니까? 다음과 같은 변형을 시도했습니다.

Dictionary<string, object> MyContainer = new Dictionary<string, object>();
mock.ExpectGet<object>( p => p[It.IsAny<string>()]).Returns(MyContainer[(string s)]);

그러나 그것은 컴파일되지 않습니다.

내가 MOQ로 달성하려는 것이 가능합니까? 누군가 내가 어떻게 할 수 있는지에 대한 예가 있습니까?


모의 선언문을 보여주지 않기 때문에 무엇을하려고하는지 명확하지 않습니다. 사전을 조롱하려고합니까?

MyContainer[(string s)] 유효한 C #이 아닙니다.

이것은 다음을 컴파일합니다.

var mock = new Mock<IDictionary>();
mock.SetupGet( p => p[It.IsAny<string>()]).Returns("foo");

Ash, HTTP 세션 모의를 사용하려면 다음 코드가 작업을 수행합니다.

/// <summary>
/// HTTP session mockup.
/// </summary>
internal sealed class HttpSessionMock : HttpSessionStateBase
{
    private readonly Dictionary<string, object> objects = new Dictionary<string, object>();

    public override object this[string name]
    {
        get { return (objects.ContainsKey(name)) ? objects[name] : null; }
        set { objects[name] = value; }
    }
}

/// <summary>
/// Base class for all controller tests.
/// </summary>
public class ControllerTestSuiteBase : TestSuiteBase
{
    private readonly HttpSessionMock sessionMock = new HttpSessionMock();

    protected readonly Mock<HttpContextBase> Context = new Mock<HttpContextBase>();
    protected readonly Mock<HttpSessionStateBase> Session = new Mock<HttpSessionStateBase>();

    public ControllerTestSuiteBase()
        : base()
    {
        Context.Expect(ctx => ctx.Session).Returns(sessionMock);
    }
}

제대로 발견으로이 뚜렷한 방법이 있습니다 SetupGetSetupSet각각 getter 및 setter를 초기화 할 수 있습니다. 하지만이 SetupGet속성이 아니라 인덱서를 사용하기위한 것입니다, 당신이 그것을 전달 키를 처리 할 수 없습니다. 정확하게 말하면 인덱서의 SetupGet경우 Setup어쨌든 다음 을 호출 합니다.

internal static MethodCallReturn<T, TProperty> SetupGet<T, TProperty>(Mock<T> mock, Expression<Func<T, TProperty>> expression, Condition condition) where T : class
{
  return PexProtector.Invoke<MethodCallReturn<T, TProperty>>((Func<MethodCallReturn<T, TProperty>>) (() =>
  {
    if (ExpressionExtensions.IsPropertyIndexer((LambdaExpression) expression))
      return Mock.Setup<T, TProperty>(mock, expression, condition);
    ...
  }
  ...
}

질문에 답하기 위해 다음은 기본 Dictionary값을 저장 하는 사용하는 코드 샘플입니다 .

var dictionary = new Dictionary<string, object>();

var applicationSettingsBaseMock = new Mock<SettingsBase>();
applicationSettingsBaseMock
    .Setup(sb => sb[It.IsAny<string>()])
    .Returns((string key) => dictionary[key]);
applicationSettingsBaseMock
    .SetupSet(sb => sb["Expected Key"] = It.IsAny<object>())
    .Callback((string key, object value) => dictionary[key] = value);

보시다시피 인덱서 setter를 설정하려면 명시 적으로 키를 지정해야합니다. 자세한 내용은 다른 SO 질문에 설명되어 있습니다. Moq 인덱싱 된 속성 및 반환 / 콜백에서 인덱스 값 사용


그다지 어렵지는 않지만 그것을 찾는 데 조금 걸렸습니다. :)

var request = new Moq.Mock<HttpRequestBase>();
request.SetupGet(r => r["foo"]).Returns("bar");

내가 MOQ로하려는 것이 불가능한 것 같습니다.

Essentially I was attempting to MOQ a HTTPSession type object, where the key of the item being set to the index could only be determined at runtime. Access to the indexed property needed to return the value which was previously set. This works for integer based indexes, but string based indexes do not work.

참고URL : https://stackoverflow.com/questions/340827/how-to-moq-an-indexed-property

반응형