public
interface
IFoo
{
int
Foo {
set
; }
}
[TestMethod]
public
void
TestSetOnlyProperty()
{
IFoo fooMock = Mock.Create<IFoo>();
fooMock.Foo = 30;
Mock.AssertSet(() => fooMock.Foo = 30);
}
public
interface
IFooGetAndSet
{
int
Foo {
get
;
set
; }
}
[TestMethod]
public
void
TestSetProperty()
{
IFooGetAndSet fooMock = Mock.Create<IFooGetAndSet>();
fooMock.Foo = 30;
Mock.AssertSet(() => fooMock.Foo = 30);
}
I have a simple 'Service' system set up with an interface as shown below. I am trying to mock it for use in my unit testing, but am having a bit of an obstacle. The way it works is that I design classes that implement IRequestFor<T,R>
and I would call the service bus like this...
var member = new Member { Name = "valid@email.com", Password = "validPassword" };
ServiceBus.Query<ValidateUser>().With(member);
This works fine in my code. I have no issues with it. But when I try to mock it, like this ..
var service = Mock.Create<IServiceBus>();
// Model
var model = new Web.Models.Membership.Login
{
Email = "acceptible@email.com",
Password = "acceptiblePassword",
RememberMe = true
};
// Arrange
Mock.Arrange(() => service.Query<Membership.Messages.ValidateMember>().With(model))
.Returns(true);
I am given the following error.
NullReferenceException
I don't even know what the exception is on. It 'points' to the ServiceBus in my Controller code, and if I use the debugger, the object is like .. {IServiceBus_Proxy_2718486e043f432da4b143c257cef8ce}
, but other than that, everything else looks the exact same as if I step through it in a normal run.
I am using Telerik JustMock for the mocking, but I don't know how I would do this in a different mocking framework either. I am using Ninject for my Dependency Injection, as well. Can anyone help me?
For convenience, I have included as much of my code as possible below.
public interface IServiceBus
{
T Query<T>() where T : IRequest;
T Dispatch<T>() where T : IDispatch;
}
public interface IRequest
{
}
public interface IDispatch
{
}
public interface IRequestFor<TResult> : IRequest
{
TResult Reply();
}
public interface IRequestFor<TParameters, TResult> : IRequest
{
TResult With(TParameters parameters);
}
public interface IDispatchFor<TParameters> : IDispatch
{
void Using(TParameters parameters);
}
public class ServiceBus : IServiceBus
{
private readonly IKernel kernel;
public ServiceBus(IKernel kernel) {
this.kernel = kernel;
}
/// <summary>
/// Request a query behavior that may be given parameters to yield a result.
/// </summary>
/// <typeparam name="T">The type of query to request.</typeparam>
/// <returns></returns>
public T Query<T>() where T : IRequest
{
// return a simple injected instance of the query.
return kernel.Get<T>();
}
/// <summary>
/// Request a dispatch handler for a given query that may be given parameters to send.
/// </summary>
/// <typeparam name="T">The type of handler to dispatch.</typeparam>
/// <returns></returns>
public T Dispatch<T>() where T : IDispatch
{
// return a simple injected instance of the dispatcher.
return kernel.Get<T>();
}
}
Bind<IServiceBus>()
.To<ServiceBus>()
.InSingletonScope();
[TestMethod]
public void Login_Post_ReturnsRedirectOnSuccess()
{
// Inject
var service = Mock.Create<IServiceBus>();
var authenticationService = Mock.Create<System.Web.Security.IFormsAuthenticationService>();
// Arrange
var controller = new Web.Controllers.MembershipController(
service, authenticationService
);
var httpContext = Mock.Create<HttpContextBase>();
// Arrange
var requestContext = new RequestContext(
new MockHttpContext(),
new RouteData());
controller.Url = new UrlHelper(
requestContext
);
// Model
var model = new Web.Models.Membership.Login
{
Email = "acceptible@email.com",
Password = "acceptiblePassword",
RememberMe = true
};
// Arrange
Mock.Arrange(() => service.Query<Membership.Messages.ValidateMember>().With(model))
.Returns(true);
// Act
var result = controller.Login(model, "/Home/");
// Assert
Assert.IsInstanceOfType(result, typeof(RedirectResult));
}
public class ValidateMember : IRequestFor<IValidateMemberParameters, bool>
{
private readonly ISession session;
public ValidateMember(ISession session) {
this.session = session;
}
public bool With(IValidateMemberParameters model)
{
if (String.IsNullOrEmpty(model.Email)) throw new ArgumentException("Value cannot be null or empty.", "email");
if (String.IsNullOrEmpty(model.Password)) throw new ArgumentException("Value cannot be null or empty.", "password");
// determine if the credentials entered can be matched in the database.
var member = session.Query<Member>()
.Where(context => context.Email == model.Email)
.Take(1).SingleOrDefault();
// if a member was discovered, verify their password credentials
if( member != null )
return System.Security.Cryptography.Hashing.VerifyHash(model.Password, "SHA512", member.Password);
// if we reached this point, the password could not be properly matched and there was an error.
return false;
}
}
var urlHelper = Mock.Create<
UrlHelper
>( Constructor.Mocked );
Mock.Arrange( () => urlHelper.Action( Arg.IsAny<
string
>(), Arg.IsAny<
string
>() ) )
.DoInstead( ( string actionName, string controllerName ) => {} )
.Returns( ( string actionName, string controllerName ) => String.Format( "/{0}/{1}", controllerName, actionName ) );
Mock.SetupStatic<EagleUtility>();
Mock.Arrange(() => EagleUtility.ValidateMessage(Arg.IsAny<
byte
[]>(), Arg.AnyInt, TowerTypes.Unified)).
DoNothing().Returns(
true
).MustBeCalled();
Argument Exception
Could not resolve the target method; make sure that you have provided arguments correctly.
Code:public interface IBase { } public abstract class BaseClass { } public class AssignedClass : BaseClass { } public class WrapperClass<T> : IBase where T : BaseClass, new() { } public class Control { private WrapperClass<AssignedClass> getWrapper() { return null; } } [TestClass] public class TestFlow { [TestMethod] public void ShouldWork() { var control = Mock.Create<Control>(); var wrapper = Mock.Create<WrapperClass<AssignedClass>>(); //Dosent Work Mock.NonPublic.Arrange<WrapperClass<AssignedClass>>(control, "getWrapper").Returns(wrapper); //Dosent Work Mock.NonPublic.Arrange<IBase>(control, "getWrapper").Returns(wrapper); } }