【发布时间】:2018-08-11 20:33:01
【问题描述】:
我正在使用 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 被调用并返回到被测单元。它继续正确,反序列化并返回没有问题。
但是一旦它返回到我的测试方法中,我可以看到返回的对象不是空的,因为调试器显示了它的类型,但是如果我尝试向下钻取,大约需要 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; }
}
【问题讨论】:
-
你能给我们看看你的测试吗?
标签: .net unit-testing task moq xunit