我有一个测试,可以从端点获取某些设备状态。我有反应嘲笑并正确获取信息。我想要实现的测试必须获取此信息,并在一段时间后再次获取该信息并检查是否与抛出事件不同。问题是我无法在测试中更改模拟的响应。这就是我的尝试。
模拟WebRequest的实现。
class TestWebRequestCreate : IWebRequestCreate
{
public TestWebRequest testWebRequest { get; set; }
public WebRequest Create(Uri uri)
{
WebRequest webRequest;
if (testWebRequest == null)
{
webRequest = new TestWebRequest(HttpStatusCode.OK, "Testing response");
}
else
{
webRequest = testWebRequest;
}
return webRequest;
}
}
class TestWebRequest : WebRequest
{
public HttpStatusCode httpStatusCode { get; set; }
public Stream responseMessage;
/// <summary>
/// Initialize a new instance of <see cref="TestWebRequest"/>
/// with the response to return
/// </summary>
public TestWebRequest(HttpStatusCode httpStatusCode, string responseMessage)
{
this.httpStatusCode = httpStatusCode;
this.responseMessage = StreamFromString(responseMessage);
}
public override WebResponse GetResponse()
{
MemoryStream responseCopy = new MemoryStream();
//Stream responseCopy = new MemoryStream();
responseMessage.Position = 0;
responseMessage.CopyTo(responseCopy);
//Reset position after reading Streams
responseCopy.Position = 0;
Mock<HttpWebResponse> mockHttpWebResponse = new Mock<HttpWebResponse>();
mockHttpWebResponse.Setup(r => r.StatusCode).Returns(httpStatusCode);
mockHttpWebResponse.Setup(r => r.GetResponseStream()).Returns(responseCopy);
return mockHttpWebResponse.Object;
}
在我的测试之后,我这样做:
public void DeviceChangedEvent_WhenDeviceHaveChanged_EventIsThrown()
{
string uri = new UriBuilder(TESTHOSTPREFFIX, TESTCORRECTHOST, TESTPORT, TESTDEVICEENDPOINT).ToString();
bool wasThrown = false;
m_deviceRetriever.Init(m_serviceProvider);
m_deviceRetriever.Start();
m_deviceRetriever.DeviceChangeEvent += (DeviceRetrieverOnDeviceChangeEvent, args) =>
{
wasThrown = true;
};
Thread.Sleep(5000);
//Change device XML to simulate the change
var namespaceManager = new XmlNamespaceManager(m_correctMockedXmlDevice.NameTable);
namespaceManager.AddNamespace("ps", "http://www.hp.com/ps/fall15");
XmlNode printheadIdNode = m_correctMockedXmlDevices.SelectSingleNode("/ps:DevicesStatus/DeviceSlotCollection/DeviceSlot/SlotId", namespaceManager);
deviceIdNode.InnerText = "Changed";
m_testWebRequestCreateCorrectDevices = null;
m_testWebRequestCreateCorrectDevices = new TestWebRequestCreate
{
testWebRequest = new TestWebRequest(HttpStatusCode.OK, m_correctMockedXmlDevices.InnerXml)
};
Thread.Sleep(5000);
//We give some time to get the new state of printheads
Assert.IsTrue(wasThrown);
}
}
在测试之前我准备创建这个
private void CreateCorrectDevicesMockEndpoint()
{
string uri = new UriBuilder(TESTHOSTPREFFIX, TESTCORRECTHOST, TESTPORT, TESTPRINTHEADSENDPOINT).ToString();
m_testWebRequestCreateCorrectDevices = new TestWebRequestCreate();
m_correctMockedXmlDevices = new XmlDocument();
m_correctMockedXmlDevices.Load("pathToXMLFile");
m_testWebRequestCreateCorrectDevices.testWebRequest = new TestWebRequest(HttpStatusCode.OK, m_correctMockedXmlPrintheads.InnerXml);
WebRequest.RegisterPrefix(uri, m_testWebRequestCreateCorrectDevices);
}
编辑: 我的测试设置是初始化所有必要的依赖项。
public void SetUp()
{
m_serviceProvider = new ServiceProvider();
m_serviceProvider.Add<ILogger>(new Mock<ILogger>().Object);
m_deviceRetriever = new DeviceRetriever();
m_connectivitySettings = new ConnectivitySettings() { IpAddress = TESTCORRECTHOST };
m_serviceProvider.Add<ConnectivitySettings>(m_connectivitySettings);
CreateCorrectDevicesMockEndpoint();
}
我没有收到任何错误,问题是我的mock返回的XML没有改变。谢谢你的帮助!
答案 0 :(得分:1)
正如我在评论中所说,我相信你的问题出现在你没有向我们展示的代码中。您设置的模拟工作正常,但它依赖于您GetResponse
的正确实例上的TestWebRequest
来电。我的信念是,无论您是在进行轮询,您都不会更新轮询器正在使用的TestWebRequestCreate
实例,因此它只是使用原始模拟创建TestWebRequest
设置的另一个实例。下面是一个示例,完整的测试,说明您的模拟工作,可以从不同的线程访问并按预期工作。
bool wasThrown = false;
IWebRequestCreate m_testWebRequestCreateCorrectDevices = null;
[TestMethod]
public void TestThreadedWebRequest()
{
const string errorResponse = "Some Error Text";
m_testWebRequestCreateCorrectDevices = new TestWebRequestCreate();
var uri = new Uri(@"http:\\www.stackoverflow.com");
wasThrown = false;
var thread = new System.Threading.Thread(() =>
{
while (true)
{
var creator = m_testWebRequestCreateCorrectDevices;
if (creator != null)
{
var message = creator.Create(uri);
var response = new StreamReader(message.GetResponse()
.GetResponseStream()).ReadToEnd();
if (response == errorResponse)
{
wasThrown = true;
break;
}
}
System.Threading.Thread.Sleep(500);
}
});
thread.Start();
System.Threading.Thread.Sleep(5000);
Assert.AreEqual(false, wasThrown);
m_testWebRequestCreateCorrectDevices = null;
m_testWebRequestCreateCorrectDevices = new TestWebRequestCreate
{
testWebRequest = new TestWebRequest(HttpStatusCode.OK, errorResponse)
};
System.Threading.Thread.Sleep(5000);
Assert.AreEqual(true, wasThrown);
if (!thread.Join(1000))
{
thread.Abort();
}
}
请注意,在现有代码中,您将m_testWebRequestCreateCorrectDevices
设置为创建正确模拟响应的新邮件创建者的实例。除非您的生产代码引用此变量(在我上面的示例中就是这种情况),否则这可能不够。