我正在使用Moq和xUnit为UWP应用程序编写单元测试。我用以下代码编写了一个自定义HttpClient模拟和响应消息:
public sealed class HttpClientMock : IHttpClient
{
private string _response;
public HttpClientMock(string response)
{
_response = response;
}
public bool SimulateBasStatusCode { get; set; }
public TimeSpan Timeout { get; set; }
public void Dispose()
{ }
public async Task<IHttpResponseMessage> GetAsync(string request)
{
IHttpResponseMessage response = new HttpResponseMessageMock(_response);
return await Task.FromResult(response);
}
}
public sealed class HttpResponseMessageMock : IHttpResponseMessage
{
private string _response;
public HttpResponseMessageMock(string response)
{
_response = response;
}
public bool SimulateBadSuccessStatusCode { get; set; }
public bool IsSuccessStatusCode
{
get
{
return !SimulateBadSuccessStatusCode;
}
}
public async Task<string> ReadAsStringAsync()
{
return await Task.FromResult(_response);
}
}
被测单位是这样的:
internal async Task<T> GetAndSerialize<T>(string request)
{
T res = default(T);
using (_httpClient)
{
_httpClient.Timeout = TimeSpan.FromMinutes(3);
IHttpResponseMessage response = await _httpClient.GetAsync(request);
if (response.IsSuccessStatusCode)
{
string xml = await response.ReadAsStringAsync();
XmlSerializer serializer = new XmlSerializer(typeof(T));
StringReader reader = new StringReader(xml);
res = (T)serializer.Deserialize(reader);
}
}
return res;
}
在最后一个类中,_httpClient被推送到测试类构造函数下的单元,在这种情况下,它是我的HttpClientMock类。
启动测试时,可以看到正在调用GetAndSerialize。然后,它调用HttpClientMock并正确返回HttpResponseMessageMock的实例,但调试器开始变得非常缓慢,并抱怨System.Threadind.Tasks.Task.SetNotificationForWaitCompletion超时。
我继续,可以看到我的HttpResponseMessageMock的ReadAsStringAsync被调用并返回到被测单元中。它可以正确继续,可以反序列化,然后可以正常返回。
但是一旦返回到我的测试方法中,我就可以看到返回的对象不是null,因为调试器显示了它的类型,但是如果我尝试向下钻取,则大约需要5秒钟并且仅显示“?”。没有显示属性。
稍后在测试中,我对返回的对象的属性进行断言,并将其视为null。
我尝试并搜索了三个小时,但均未成功。你有什么建议吗?
这是测试类的缩写版本:
public class TestClass
{
private const string OBJECT_MOCK = "<ObjectMock testResponse='Test Value'/>";
[Fact]
public async Task FailTest()
{
/////
// Arrange
IHttpClient httpClient = new HttpClientMock(OBJECT_MOCK);
TestedService mySvc = new TestesService(httpClient);
/////
// Act
ObjectMock response = await mySvc.GetAndSerialize<ObjectMock>("/TestRelativeURL");
/////
// Assert
Assert.NotNull(response);
Assert.Equal("Test Value", response.TestResponse);
}
}
这是ObjectMock类:
[Serializable]
[XmlRoot("ObjectMock")]
public sealed class ObjectMock
{
[XmlElement("testResponse")]
public string TestResponse { get; set; }
}
答案 0 :(得分:1)
这是我的错误,是在帖子中添加ObjectMock类时发现的。我推送的序列化版本为for
,但是在ObjectMock类中,testResponse属性被注释为XmlElement。
当我将其更正为XmlAttribute时,不再有延迟,没有SetNotificationForWaitCompletion超时,并且在我的测试方法中正确声明了属性值。
我想XmlElement / XmlAttribute反转会导致异常,从而导致任务延迟并导致超时。
另一个rubber duck debugging获胜!