I have a RelayCommand
that I am trying to test. The RelayCommand
contains a Service Call
to Authenticate my user. Shown below:
private MvxCommand _signIn;
public MvxCommand SignIn
{
get
{
return _signIn ?? (_signIn = new MvxCommand(() =>
{
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
EndpointAddress endpoint = new EndpointAddress(AppResources.AuthService);
var client = new MyService(binding, endpoint);
client.AuthorizeCompleted += ((sender, args) =>
{
try
{
if (args.Result)
{
//Success.. Carry on
}
}
catch (Exception ex)
{
//AccessDenied Exception thrown by service
if (ex.InnerException != null && string.Equals(ex.InnerException.Message, "Access is denied.", StringComparison.CurrentCultureIgnoreCase))
{
//Display Message.. Incorrect Credentials
}
else
{
//Other error... Service down?
}
}
});
client.AuthorizeAsync(UserName, Password, null);
}));
}
}
But now I am using NUnit
to test my ViewModels
and I am stumped on how to test my RelayCommand
I can do:
[Test]
public void PerformTest()
{
ViewModel.SignIn.Execute();
}
But this returns no information on whether the SignIn
method succeeded or not.
How do I test a RelayCommand
containing a Service Call
?
So in the end I used Dependency Injection
to inject a service into the constructor of my viewmodel like so:
public IMyService client { get; set; }
public MyClass(IMyService myservice)
{
client = myservice
}
I can then refactor my SignIn
method like so:
private MvxCommand _signIn;
public MvxCommand SignIn
{
get
{
return _signIn ?? (_signIn = new MvxCommand(() =>
{
client.AuthorizeCompleted += ((sender, args) =>
{
try
{
if (args.Result)
{
//Success.. Carry on
}
}
catch (Exception ex)
{
//AccessDenied Exception thrown by service
if (ex.InnerException != null && string.Equals(ex.InnerException.Message, "Access is denied.", StringComparison.CurrentCultureIgnoreCase))
{
//Display Message.. Incorrect Credentials
}
else
{
//Other error... Service down?
}
}
});
client.AuthorizeAsync(UserName, Password, null);
}));
}
}
and test my ViewModel
using a mock service using the Assign-Act-Assert design pattern:
[Test]
public void PerformTest()
{
List<object> objs = new List<object>();
Exception ex = new Exception("Access is denied.");
objs.Add(true);
AuthorizeCompletedEventArgs incorrectPasswordArgs = new AuthorizeCompletedEventArgs(null, ex, false, null);
AuthorizeCompletedEventArgs correctPasswordArgs = new AuthorizeCompletedEventArgs(objs.ToArray(), null, false, null);
Moq.Mock<IMyService> client = new Mock<IMyService>();
client .Setup(t => t.AuthorizeAsync(It.Is<string>((s) => s == "correct"), It.Is<string>((s) => s == "correct"))).Callback(() =>
{
client.Raise(t => t.AuthorizeCompleted += null, correctPasswordArgs);
});
client.Setup(t => t.AuthorizeAsync(It.IsAny<string>(), It.IsAny<string>())).Callback(() =>
{
client.Raise(t => t.AuthorizeCompleted += null, incorrectPasswordArgs);
});
var ViewModel = new MyClass(client.Object);
ViewModel.UserName = "correct";
ViewModel.Password = "correct";
ViewModel.SignIn.Execute();
}