2013-02-06 47 views
0

我正在爲從Request.InputStream中讀取POST正文的WebApi控制器編寫單元測試。我需要設置HttpContext.Current.Request.InputStream的inputstream屬性,或者設置輸入流的內容。這裏是我的單元測試代碼,到目前爲止,但它不斷拋出異常:如何使用反射設置HttpRequest.InputStream值

var originalStream = HttpContext.Current.Request.InputStream; 
Stream newStream = new MemoryStream(ASCIIEncoding.Default.GetBytes("Test String")); 

var propInfo = originalStream.GetType().GetProperty("CanWrite"); 
propInfo.SetValue(originalStream, true); 

newStream.CopyTo(originalStream); 

propInfo.SetValue(originalStream, false); 

我上線的SetValue以下情況除外:

ArgumentException: Property set method not found 

我要對所有這一切錯了嗎?我的控制器讀取輸入流並將其反序列化爲JSON,因此我需要能夠將數據插入到該流中。我只是不知道該怎麼做。非常感謝。

回答

1

public abstract bool CanWrite { get; }。那個屬性沒​​有setter,因此你的錯誤。

在你的例子中,originalStream將是Stream類型。將它包裝在另一個流中進行測試。你是不是測試HttpRequest.InputStream,你正在測試的反序列化...

var originalStream = new StreamReader(HttpContext.Current.Request.InputStream); 
var content = originalStream.ReadToEnd(); 

..等

你甚至可以考慮完全使用輸入的請求跳過,因爲你並沒有真正測試的是。

編輯:

要擴大一點。你應該將這個出了控制器動作..執行類似下面的:

public class YourController : Controller { 
    private readonly IStreamWrapper _streamWrapper; 

    public YourController(IStreamWrapper wrapper) { 
     _streamWrapper = wrapper; 
    } 

    public ActionResult MethodYouAreTesting() { 
     var result = _streamWrapper.Process(HttpRequest.InputStream); 
    } 
} 

public class Tests { 
    public void YourTestMethod() { 
     var controller = new YourController(new FakeStreamWrapper()); // mock perhaps? 
     // Asserts here for the controller action 
    } 

    public void YourWrapperTester() { 
     var wrapper = new RealStreamWrapper(); 
     // test Process method here.. 
    } 
} 

然後你就可以測試流讀取和孤立的反序列化。

這是否有意義或讓我更復雜? :/

+0

我正在測試我的控制器的操作。爲了得到請求主體,我的控制器執行Context.Current.Request.InputStream.Read(基本上),所以我需要能夠設置它。我無法將身體傳遞給我的行動。我不明白你的方法會如何工作。 – dmoss18

+0

雖然這是我的觀點。我會把邏輯轉移到它自己的類中。將其注入到控制器中,然後使用它來測試操作。您可以將'InputStream'傳遞到這個單獨的類中,並將其包裝在更具體的實現中。你所做的比自己需要的要難得多。我會更新我的答案。 –

+0

謝謝,但我如何讓InputStream讀取我在測試方法中定義的內容?我看到你的方法如何工作,但我不明白如何告訴InputStream讀什麼。 – dmoss18

0

InputStream是一個只讀流。

有幾種方法。從最簡單的開始:

創建一個StreamReader的實例並在InputStream上調用ReadToEnd()以獲取要發送的數據。

一旦你有了內容,你可以在做你的JSON轉換之前根據需要進行修改。

再次,這是最簡單,最不優雅的方式來做你想做的事情,但它應該工作。