2009-07-25 3 views
4

Я использую Moq для создания макета объекта HttpResponseBase. Мне нужно проверить, что HttpResponseBase.End() был вызван в моей библиотеке. Чтобы сделать это, я указываю текст перед вызовом и некоторый текст после. Затем я проверяю, что только текст перед вызовом End() присутствует в HttpResponseBase.Output.Как мне высмеять HttpResponseBase.End()?

Проблема в том, что я не могу понять, как издеваться над HttpResponseBase.End(), чтобы она перестала обрабатываться, как в ASP.NET.

public static HttpResponseBase CreateHttpResponseBase() { 
    var mock = new Mock<HttpResponseBase>(); 
    StringWriter output = new StringWriter(); 

    mock.SetupProperty(x => x.StatusCode); 
    mock.SetupGet(x => x.Output).Returns(output); 
    mock.Setup(x => x.End()) /* what do I put here? */; 
    mock.Setup(x => x.Write(It.IsAny<string>())) 
     .Callback<string>(s => output.Write(s)); 

    return mock.Object; 
} 

ответ

2

Это немного для меня неясным, что именно вы пытаетесь достичь, но из вашего описания, это звучит, как вы пытаетесь получить ваш Абстракт вести себя как конкретной реализации. Другими словами, поскольку HttpResponse.End() имеет определенное поведение, вы хотите, чтобы ваш Mock имел такое же поведение?

В общем, это не очень легко сделать с Moq, так как у него нет концепции упорядоченных ожиданий (в отличие от RhinoMocks). Существует, однако, feature request for it.

Возможно, вы сможете использовать обратный вызов вместе с настройкой метода End, чтобы переключить флаг, который определяет любое дальнейшее поведение Mock, но это не будет особенно красиво. Я думаю о чем-то вроде этого:

bool ended = false; 
var mock = new Mock<HttpResponseBase>(); 
mock.Setup(x => x.End()).Callback(() => ended = true); 
// Other setups involving 'ended' and Callbacks 

Тогда есть все другие наборы имеют двойное implementatations в зависимости от того ended является истинным или ложным.

Это было бы чертовски уродливо, поэтому я серьезно пересмотрю свои варианты на этом этапе. Есть как минимум два направления, которые вы можете предпринять:

  1. Сделайте поддельную реализацию HttpResponseBase вместо использования Moq. Похоже, вы ожидаете такого конкретного поведения реализации, что Test Double со встроенной логикой звучит как лучший вариант. Короче говоря, Fake - это Test Double, который может содержать полукоммерческую логику, которая имитирует предполагаемую производственную реализацию. Вы можете узнать больше о подделках и других тестах в отличной книге xUnit Test Patterns.
  2. Пересмотреть свои первоначальные предположения. Мне кажется, что вы очень тесно привязываете своего клиента к определенному поведению HttpResponseBase, поэтому вы можете нарушать Принцип замещения Лискова. Однако я могу ошибаться, так как метод под названием «Конец» несет определенные коннотации за пределами чисто семантики, но все же я лично считаю, что лучший дизайн возможен.
+0

Спасибо! Установка флага звучит как самый простой способ. –