模拟 Azure MobileServiceClient
Mocking Azure MobileServiceClient
我有一个方法需要进行单元测试,但我被其中的模拟部分困住了。
private async void LoginCommandAsync()
{
.....
CancellationToken ct;
var result = await ClientAuthorizationService.CurrentClient.InvokeApiAsync(Constants.ApiConstants.AzureAuthMeData,
null, HttpMethod.Get, null, ct);
....
}
我尝试使用最小起订量模拟 Microsoft.WindowsAzure.MobileServices.MobileServiceClient。不幸的是,我总是在最后一行代码中得到一个 System.InvalidCastException
var currentClient = new Mock<IMobileServiceClient>(MockBehavior.Loose);
currentClient.Setup(x => x.InvokeApiAsync(Constants.ApiConstants.AzureAuthMeData,
null, HttpMethod.Get, null, ct)).Returns(Task.FromResult(token));
var disposableCurrentClient = currentClient.As<IDisposable>();
ClientAuthorizationService.CurrentClient = (MobileServiceClient)disposableCurrentClient.Object;
MobileServiceClient 继承自 IMobileServiceClient,IDisposable 但无论我如何尝试 use/assign 模拟对象...它都不起作用。
public class ClientAuthorizationService : IClientAuthorizationService
{
public MobileServiceClient CurrentClient { get; set; }
public ClientAuthorizationService()
{
CurrentClient = new MobileServiceClient(Constants.ApiConstants.ApplicationUrl);
}
}
将 ClientAuthorizationService.CurrentClient
member/property 从 MobileServiceClient
更改为 IMobileServiceClient
public interface IClientAuthorizationService {
IMobileServiceClient CurrentClient { get; set; }
}
public class ClientAuthorizationService : IClientAuthorizationService {
public ClientAuthorizationService() {
CurrentClient = new MobileServiceClient(Constants.ApiConstants.ApplicationUrl);
}
public IMobileServiceClient CurrentClient { get; set; }
}
这将允许在测试时分配客户端的模拟,因为 ClientAuthorizationService
现在依赖于抽象而不是实现问题。
//....
var clientAuthorizationService = new Mock<IClientAuthorizationService>();
var currentClient = new Mock<IMobileServiceClient>();
currentClient
.Setup(_ => _.InvokeApiAsync(It.IsAny<string>(), null, HttpMethod.Get, null, It.IsAny<CancellationToken>()))
.ReturnsAsync(token);
clientAuthorizationService
.Setup(_ => _.CurrentClient)
.Returns(currentClient.Object);
//.....
此外,建议不要使用 async void
除了事件处理程序
因此需要相应更新被测代码。
private async Task LoginCommandAsync() {
//.....
CancellationToken ct;
var result = await ClientAuthorizationService.CurrentClient.InvokeApiAsync(Constants.ApiConstants.AzureAuthMeData,
null, HttpMethod.Get, null, ct);
//....
}
我有一个方法需要进行单元测试,但我被其中的模拟部分困住了。
private async void LoginCommandAsync()
{
.....
CancellationToken ct;
var result = await ClientAuthorizationService.CurrentClient.InvokeApiAsync(Constants.ApiConstants.AzureAuthMeData,
null, HttpMethod.Get, null, ct);
....
}
我尝试使用最小起订量模拟 Microsoft.WindowsAzure.MobileServices.MobileServiceClient。不幸的是,我总是在最后一行代码中得到一个 System.InvalidCastException
var currentClient = new Mock<IMobileServiceClient>(MockBehavior.Loose);
currentClient.Setup(x => x.InvokeApiAsync(Constants.ApiConstants.AzureAuthMeData,
null, HttpMethod.Get, null, ct)).Returns(Task.FromResult(token));
var disposableCurrentClient = currentClient.As<IDisposable>();
ClientAuthorizationService.CurrentClient = (MobileServiceClient)disposableCurrentClient.Object;
MobileServiceClient 继承自 IMobileServiceClient,IDisposable 但无论我如何尝试 use/assign 模拟对象...它都不起作用。
public class ClientAuthorizationService : IClientAuthorizationService
{
public MobileServiceClient CurrentClient { get; set; }
public ClientAuthorizationService()
{
CurrentClient = new MobileServiceClient(Constants.ApiConstants.ApplicationUrl);
}
}
将 ClientAuthorizationService.CurrentClient
member/property 从 MobileServiceClient
更改为 IMobileServiceClient
public interface IClientAuthorizationService {
IMobileServiceClient CurrentClient { get; set; }
}
public class ClientAuthorizationService : IClientAuthorizationService {
public ClientAuthorizationService() {
CurrentClient = new MobileServiceClient(Constants.ApiConstants.ApplicationUrl);
}
public IMobileServiceClient CurrentClient { get; set; }
}
这将允许在测试时分配客户端的模拟,因为 ClientAuthorizationService
现在依赖于抽象而不是实现问题。
//....
var clientAuthorizationService = new Mock<IClientAuthorizationService>();
var currentClient = new Mock<IMobileServiceClient>();
currentClient
.Setup(_ => _.InvokeApiAsync(It.IsAny<string>(), null, HttpMethod.Get, null, It.IsAny<CancellationToken>()))
.ReturnsAsync(token);
clientAuthorizationService
.Setup(_ => _.CurrentClient)
.Returns(currentClient.Object);
//.....
此外,建议不要使用 async void
除了事件处理程序
因此需要相应更新被测代码。
private async Task LoginCommandAsync() {
//.....
CancellationToken ct;
var result = await ClientAuthorizationService.CurrentClient.InvokeApiAsync(Constants.ApiConstants.AzureAuthMeData,
null, HttpMethod.Get, null, ct);
//....
}