UserManager not creating users in Unit Tests - unit-testing

I'm using xUnit & Moq and what I'm trying to achieve is typically create Identity User so it's stored in Entity Framework In-Memory DB.
I have established Seed Data functionality - it gets triggered when my ASP.NET Core host app starts and works flawlessly - so no problem.
But the issue occurs when I use a mocked UserManager. No exceptions are thrown, users are just not being saved.
Verified while debugging tests, DbContext returns 0 users, also UserManager.FindByNameAsync yields null.
I wonder what is the cause. Could it be due to the way I assemble UserManager in constructor of SeedDataTest class?
public class SeedDataTest
{
private AppDbContext dbContext;
private UserManager<ApplicationUser> userManager;
private ITenantService tenantService;
public SeedDataTest()
{
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseInMemoryDatabase(databaseName: "in_memory_db")
.Options;
dbContext = new AppDbContext(options);
var userStore = new UserStore<ApplicationUser>(dbContext);
userManager = new Mock<UserManager<ApplicationUser>>(
userStore,
new Mock<IOptions<IdentityOptions>>().Object,
new Mock<IPasswordHasher<ApplicationUser>>().Object,
new IUserValidator<ApplicationUser>[0],
new IPasswordValidator<ApplicationUser>[0],
new Mock<ILookupNormalizer>().Object,
new Mock<IdentityErrorDescriber>().Object,
new Mock<IServiceProvider>().Object,
new Mock<ILogger<UserManager<ApplicationUser>>>().Object)
.Object;
tenantService = new Mock<TenantService>(dbContext).Object;
}
[Fact]
public void Test1()
{
new TenantsCreator(dbContext).Create();
new UserCreator(dbContext, tenantService, userManager).Create(); // stuck here
new MembershipCreator(dbContext, userManager).Create();
// unfinished
}
}
And here is the code from UserCreator
public class UserCreator
{
private AppDbContext _context;
private ITenantService _tenantService;
private UserManager<ApplicationUser> _userManager;
public UserCreator(
AppDbContext context,
ITenantService tenantService,
UserManager<ApplicationUser> userManager
)
{
_context = context;
_tenantService = tenantService;
_userManager = userManager;
}
public void Create()
{
Task.Run(async () => await CreateUsers()).ConfigureAwait(false).GetAwaiter().GetResult();
}
private async Task CreateUsers()
{
ApplicationUser hostAdminUser = _context.Users.FirstOrDefault(x => x.UserName.Equals(SetupConsts.Users.AdminJoe.UserName));
if (hostAdminUser == null)
{
hostAdminUser = new ApplicationUser()
{
FirstName = SetupConsts.Users.AdminJoe.FirstName,
LastName = SetupConsts.Users.AdminJoe.LastName,
UserName = SetupConsts.Users.AdminJoe.UserName,
Email = SetupConsts.Users.AdminJoe.Email,
EmailConfirmed = true,
PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(hostAdminUser, SetupConsts.Users.Passwords.Default)
};
await _userManager.CreateAsync(hostAdminUser);
}
ApplicationUser secondaryUser = _context.Users.FirstOrDefault(x => x.UserName.Equals(SetupConsts.Users.JohnRoe.UserName));
if (secondaryUser == null)
{
secondaryUser = new ApplicationUser()
{
FirstName = SetupConsts.Users.JohnRoe.FirstName,
LastName = SetupConsts.Users.JohnRoe.LastName,
UserName = SetupConsts.Users.JohnRoe.UserName,
Email = SetupConsts.Users.JohnRoe.Email,
EmailConfirmed = true,
PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(secondaryUser, SetupConsts.Users.Passwords.Default)
};
await _userManager.CreateAsync(secondaryUser);
}
}
}

we use mocking frameworks to allow us to build mocked (substituted) dependencies as well as specify what is returned from classes/interfces used within our SUT.
A good use case for this is a database itself. We always want to know the exact state of objects whilst we are testing them and the only way we do that is by expressing the content of them ourselves.
That is where Moq comes in. One of its features is to allow us to state the result of method calls.
I believe you are seeing 0 results returned because you are using a moq implementation of a class (which doesnt actually call the implemented class). In order to get a result, you will need to do some setup:
mockedClass.Setup(x => x.GetUserDetails(It.IsAny<int>())).Returns(new UserDetails());
Either do it this way, or ensure you are passing a concrete implementation of the UserManager class rather than the mocked version:
userManager = new UserManager<ApplicationUser>
Hope that helps

Related

Unit testing web api controller with role based authorization [duplicate]

I have an ASP.NET MVC Core application that I am writing unit tests for. One of the action methods uses User name for some functionality:
SettingsViewModel svm = _context.MySettings(User.Identity.Name);
which obviously fails in the unit test. I looked around and all suggestions are from .NET 4.5 to mock HttpContext. I am sure there is a better way to do that. I tried to inject IPrincipal, but it threw an error; and I even tried this (out of desperation, I suppose):
public IActionResult Index(IPrincipal principal = null) {
IPrincipal user = principal ?? User;
SettingsViewModel svm = _context.MySettings(user.Identity.Name);
return View(svm);
}
but this threw an error as well.
Couldn't find anything in the docs either...
The controller’s User is accessed through the HttpContext of the controller. The latter is stored within the ControllerContext.
The easiest way to set the user is by assigning a different HttpContext with a constructed user. We can use DefaultHttpContext for this purpose, that way we don’t have to mock everything. Then we just use that HttpContext within a controller context and pass that to the controller instance:
var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, "example name"),
new Claim(ClaimTypes.NameIdentifier, "1"),
new Claim("custom-claim", "example claim value"),
}, "mock"));
var controller = new SomeController(dependencies…);
controller.ControllerContext = new ControllerContext()
{
HttpContext = new DefaultHttpContext() { User = user }
};
When creating your own ClaimsIdentity, make sure to pass an explicit authenticationType to the constructor. This makes sure that IsAuthenticated will work correctly (in case you use that in your code to determine whether a user is authenticated).
In previous versions you could have set User directly on the controller, which made for some very easy unit tests.
If you look at the source code for ControllerBase you will notice that the User is extracted from HttpContext.
/// <summary>
/// Gets the <see cref="ClaimsPrincipal"/> for user associated with the executing action.
/// </summary>
public ClaimsPrincipal User => HttpContext?.User;
and the controller accesses the HttpContext via ControllerContext
/// <summary>
/// Gets the <see cref="Http.HttpContext"/> for the executing action.
/// </summary>
public HttpContext HttpContext => ControllerContext.HttpContext;
You will notice that these two are read only properties. The good news is that ControllerContext property allows for setting it's value so that will be your way in.
So the target is to get at that object. In Core HttpContext is abstract so it is a lot easier to mock.
Assuming a controller like
public class MyController : Controller {
IMyContext _context;
public MyController(IMyContext context) {
_context = context;
}
public IActionResult Index() {
SettingsViewModel svm = _context.MySettings(User.Identity.Name);
return View(svm);
}
//...other code removed for brevity
}
Using Moq, a test could look like this
public void Given_User_Index_Should_Return_ViewResult_With_Model() {
//Arrange
var username = "FakeUserName";
var identity = new GenericIdentity(username, "");
var mockPrincipal = new Mock<ClaimsPrincipal>();
mockPrincipal.Setup(x => x.Identity).Returns(identity);
mockPrincipal.Setup(x => x.IsInRole(It.IsAny<string>())).Returns(true);
var mockHttpContext = new Mock<HttpContext>();
mockHttpContext.Setup(m => m.User).Returns(mockPrincipal.Object);
var model = new SettingsViewModel() {
//...other code removed for brevity
};
var mockContext = new Mock<IMyContext>();
mockContext.Setup(m => m.MySettings(username)).Returns(model);
var controller = new MyController(mockContext.Object) {
ControllerContext = new ControllerContext {
HttpContext = mockHttpContext.Object
}
};
//Act
var viewResult = controller.Index() as ViewResult;
//Assert
Assert.IsNotNull(viewResult);
Assert.IsNotNull(viewResult.Model);
Assert.AreEqual(model, viewResult.Model);
}
There is also the possibility to use the existing classes, and mock only when needed.
var user = new Mock<ClaimsPrincipal>();
_controller.ControllerContext = new ControllerContext
{
HttpContext = new DefaultHttpContext
{
User = user.Object
}
};
In my case, I needed to make use of Request.HttpContext.User.Identity.IsAuthenticated, Request.HttpContext.User.Identity.Name and some business logic sitting outside of the controller. I was able to use a combination of Nkosi's, Calin's and Poke's answer for this:
var identity = new Mock<IIdentity>();
identity.SetupGet(i => i.IsAuthenticated).Returns(true);
identity.SetupGet(i => i.Name).Returns("FakeUserName");
var mockPrincipal = new Mock<ClaimsPrincipal>();
mockPrincipal.Setup(x => x.Identity).Returns(identity.Object);
var mockAuthHandler = new Mock<ICustomAuthorizationHandler>();
mockAuthHandler.Setup(x => x.CustomAuth(It.IsAny<ClaimsPrincipal>(), ...)).Returns(true).Verifiable();
var controller = new MyController(...);
var mockHttpContext = new Mock<HttpContext>();
mockHttpContext.Setup(m => m.User).Returns(mockPrincipal.Object);
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext()
{
User = mockPrincipal.Object
};
var result = controller.Get() as OkObjectResult;
//Assert results
mockAuthHandler.Verify();
I want to hit my Controllers directly and just use DI like AutoFac. To do this I first registering ContextController.
var identity = new GenericIdentity("Test User");
var httpContext = new DefaultHttpContext()
{
User = new GenericPrincipal(identity, null)
};
var context = new ControllerContext { HttpContext = httpContext};
builder.RegisterInstance(context);
Next I enable property injection when I register the Controllers.
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.Name.EndsWith("Controller")).PropertiesAutowired();
Then User.Identity.Name is populated, and I do not need to do anything special when calling a method on my Controller.
public async Task<ActionResult<IEnumerable<Employee>>> Get()
{
var requestedBy = User.Identity?.Name;
..................
I would look to implement an Abstract Factory Pattern.
Create an interface for a factory specifically for providing user names.
Then provide concrete classes, one which provides User.Identity.Name, and one that provides some other hard coded value that works for your tests.
You can then use the appropriate concrete class depending on production versus test code. Perhaps looking to pass the factory in as a parameter, or switching to the correct factory based on some configuration value.
interface IUserNameFactory
{
string BuildUserName();
}
class ProductionFactory : IUserNameFactory
{
public BuildUserName() { return User.Identity.Name; }
}
class MockFactory : IUserNameFactory
{
public BuildUserName() { return "James"; }
}
IUserNameFactory factory;
if(inProductionMode)
{
factory = new ProductionFactory();
}
else
{
factory = new MockFactory();
}
SettingsViewModel svm = _context.MySettings(factory.BuildUserName());
I got a brownfield .net 4.8 project that I needed to convert to .net 5.0 and I wanted to keep as much of the original code as possible, including the unit-/integration tests. The test for Controllers relied on the Context a lot so I created this Extension method to enable setting tokens, claims and headers:
public static void AddContextMock(
this ControllerBase controller,
IEnumerable<(string key, string value)> claims = null,
IEnumerable<(string key, string value)> tokens = null,
IEnumerable<(string key, string value)> headers = null)
{
HttpContext mockContext = new DefaultHttpContext();
if(claims != null)
{
mockContext.User = SetupClaims(claims);
}
if(tokens != null)
{
mockContext.RequestServices = SetupTokens(tokens);
}
if(headers != null)
{
SetupHeaders(mockContext, headers);
}
controller.ControllerContext = new ControllerContext()
{
HttpContext = mockContext
};
}
private static void SetupHeaders(HttpContext mockContext, IEnumerable<(string key, string value)> headers)
{
foreach(var header in headers)
{
mockContext.Request.Headers.Add(header.key, header.value);
}
}
private static ClaimsPrincipal SetupClaims(IEnumerable<(string key, string value)> claimValues)
{
var claims = claimValues.Select(c => new Claim(c.key, c.value));
return new ClaimsPrincipal(new ClaimsIdentity(claims, "mock"));
}
private static IServiceProvider SetupTokens(IEnumerable<(string key, string value)> tokenValues)
{
var mockServiceProvider = new Mock<IServiceProvider>();
var authenticationServiceMock = new Mock<IAuthenticationService>();
var authResult = AuthenticateResult.Success(
new AuthenticationTicket(new ClaimsPrincipal(), null));
var tokens = tokenValues.Select(t => new AuthenticationToken { Name = t.key, Value = t.value });
authResult.Properties.StoreTokens(tokens);
authenticationServiceMock
.Setup(x => x.AuthenticateAsync(It.IsAny<HttpContext>(), null))
.ReturnsAsync(authResult);
mockServiceProvider.Setup(_ => _.GetService(typeof(IAuthenticationService))).Returns(authenticationServiceMock.Object);
return mockServiceProvider.Object;
}
This uses Moq but can be adapted to other mocking frameworks. The authentication type is hardcoded to "mock" since I rely on default authentication but this could be supplied as well.
It is used as such:
_controllerUnderTest.AddContextMock(
claims: new[]
{
(ClaimTypes.Name, "UserName"),
(ClaimTypes.MobilePhone, "1234"),
},
tokens: new[]
{
("access_token", "accessTokenValue")
},
headers: new[]
{
("header", "headerValue")
});
If you're using Razor pages and want to override the claims:
[SetUp]
public void Setup()
{
var user = new ClaimsPrincipal(new ClaimsIdentity(
new Claim[] {
new("dateofbirth", "2000-10-10"),
new("surname", "Smith") },
"mock"));
_razorModel = new RazorModel()
{
PageContext = new PageContext
{
HttpContext = new DefaultHttpContext() { User = user }
}
};
}

Error when attempting to run my XUnit Tests

I wrote a few tests in XUnit to test my data access layer. I instantiated my DAL objects & configs the same way I would if I were using it in the actual web application(this is configured to run against a dev environment for testing purposes), however XUnit throws an error:
Message: The following constructor parameters did not have matching fixture data: IConfiguration config, IMediaDataAccess media
I'm a bit new to XUnit, so unsure what the problem is. Normally ASP.NET would inject instances of IConfiguration and IMediaDataAccess for me, but that doesn't seem to be the case here.
My Test class & a sample test case:
public class DataAccessLayerTests
{
public IConfiguration Config { get; set; }
private IMediaDataAccess mediaData;
public IMediaDataAccess MediaData { get => mediaData; set => mediaData = value; }
public DataAccessLayerTests(IConfiguration config, IMediaDataAccess media)
{
this.MediaData = media;
this.Config = config;
}
public void GetAllMediaAsync_MediaListIsReturned()
{
List<Media> testData = mediaData.GetAllMedia().Result;
Assert.IsType<List<Media>>(testData);
}
}
The test(s) all fail due to the following error: Message: The following constructor parameters did not have matching fixture data: IConfiguration config, IMediaDataAccess media
For anyone else having this problem, Alexey's comment is correct. You need to download a mocking framework (like Moq) and use it to mock up the dependencies your code is expecting. For example, below is one of my fixed unit tests:
public void IndexDataModel_ShouldDisplayMedia()
{
var mockLogger = new Mock<ILogger<IndexModel>>();
var mockDataAccess = new Mock<IMediaDataAccess>();
mockDataAccess.Setup(media => media.GetAllMedia()).ReturnsAsync(GetTestMedia());
IndexModel indexController = new IndexModel(mockDataAccess.Object, mockLogger.Object);
var result = indexController.OnGet();
var viewResult = Assert.IsType<PageResult>(result);
var model = Assert.IsAssignableFrom<IEnumerable<Media>>(
indexController.mediaList);
}
The trick is you need to mock up anything that you normally depend on getting injected into your constructor, in my case this was:
var mockLogger = new Mock<ILogger<IndexModel>>();
var mockDataAccess = new Mock<IMediaDataAccess>();
My constructor takes both an ILogger and an IMediaDataAccess, so I needed to mock those. Additionally, the other code is there to provide dummy return values when your mocked dependencies are used by the test. This is done with the .Setup line of code. All this does(I think) is when GetAllMedia() is called, the mock object returns the contents of GetTestMedia() instead of needing to make the actual calls. Just make sure whatever function you write has the same return type as the real function. For reference, this is my GetTestMedia() function:
private List<Media> GetTestMedia()
{
var listMedia = new List<Media>();
Media testMedia = new Media
{
Description = "TestDesc",
Genre = "TestGenre",
Name = "TestName",
Rating = MediaRating.Excellent,
Type = MediaType.Movie,
Id = 1
};
listMedia.Add(testMedia);
Media testMedia2 = new Media
{
Description = "TestDesc2",
Genre = "TestGenre2",
Name = "TestName2",
Rating = MediaRating.Poor,
Type = MediaType.Music,
Id = 2
};
listMedia.Add(testMedia2);
return listMedia;
}

Testing Using NUnit and Moq: use case

I have a business class that manage a USER entity.
In this class I have a method to return a single user by id:
public Utente GetUser(int id)
{
var utente = _userDataManager.GetUserById(id);
return _mapper.Map<Utente>(utente);
}
_userDataManager is an interface, IUSERDATAMANAGER, and it has implemented with a DAL class; GetUserById return a user or null (search made with EF6).
_mapper is a IMAPPER interface (automapper).
The method return is the mapped object.
I have two question:
Does it make sense to test this method?
Should I mock both the object?
A black-boxed example will be appreciated.
Does it make sense to test this method?
If it is worth writing the code it is worth testing the code.
Should I mock both the object?
When testing a subject under test, you mock the dependencies that would allow the test to be exercised to completion.
For example
public void GetUser_Should_Return_Utente() {
//Arrange
var userId = 2;
var user = new User {
UserId = userId,
//... other properties
};
var userDataManagerMock = new Mock<IUserDataManager>();
userDataManagerMock.Setup(_ => _.GetUserById(userId)).Returns(user);
var expected = new Utente {
Id = user.Id,
//...other properties
}
var mapperMock = new Mock<IMapper>();
mapperMock.Setup(_ => _.Map<Utente>(It.IsAny<object>())).Returns(expected);
var subject = new MyBusinessClass(userDataManagerMock.Object, mapperMock.Object);
//Act
var actual = subject.GetUser(userId);
//Assert
Assert.Equal(expected, actual);
}
In the above code the user data manager and the mapper a mocked and injected into the subject when testing the GetUser method.
This is an isolated unit test of the above method and shows the the current implementation of that method will flow to completion provided the dependencies perform as expected during invocation.

Unit testing when Database is involved

I'm quite new to unit testing and I need an hand to understand if I'm doing things in the correct way. My major problem is regarding the DB testing... Here's my code then I'll expose my perplexities
Consider this class that's an item of a pipeline I've to perform
public class RetrieveApplicationUsernamePipelineStep : IPipelineStep
{
public const string RetrieveApplicationUsernameKey = "RetrieveApplicationUsername";
private readonly IRetrieveApplicationUserRepository repository;
public int Order => 3;
public string Name => RetrieveApplicationUsernameKey;
public RetrieveApplicationUsernamePipelineStep(IRetrieveApplicationUserRepository repository)
{
this.repository = repository;
}
public async Task<IDictionary<string, object>> Action(IDictionary<string, object> context)
{
string res = await repository.GetApplicationUser(context);
context[Resources.ApplicationUser] = res;
return context;
}
}
I wrote the following tests
[TestFixture]
public class RetrieveApplicationUsernamePipelineStepTests
{
private IRetrieveApplicationUserRepository retrieveApplicationUserRepository;
[OneTimeSetUp]
public void Start()
{
var configuration = new ConfigurationFromConfigFile();
retrieveApplicationUserRepository = new RetrieveApplicationUserRepository(configuration);
}
[Test]
public async Task ActionSuccessfullyCompleted()
{
var context = new Dictionary<string, object>();
var repository = Substitute.For<IRetrieveApplicationUserRepository>();
repository.GetApplicationUser(context).Returns("user1");
var pipeline = new RetrieveApplicationUsernamePipelineStep(repository);
var res = await pipeline.Action(context);
Assert.IsNotNull(res[Resources.ApplicationUser]);
Assert.IsNotEmpty((string)res[Resources.ApplicationUser]);
}
[Test]
public void ActionFailingCompleted()
{
var context = new Dictionary<string, object>();
var repository = Substitute.For<IRetrieveApplicationUserRepository>();
repository.GetApplicationUser(context).Throws(new UserMappingNotFoundException());
var pipeline = new RetrieveApplicationUsernamePipelineStep(repository);
Assert.ThrowsAsync<UserMappingNotFoundException>(async () => await pipeline.Action(context));
}
[Test]
public void NameTest()
{
var pipeline = new RetrieveApplicationUsernamePipelineStep(retrieveApplicationUserRepository);
Assert.IsTrue(pipeline.Name == RetrieveApplicationUsernamePipelineStep.RetrieveApplicationUsernameKey);
}
[Test]
public void OrderTest()
{
var pipeline = new RetrieveApplicationUsernamePipelineStep(retrieveApplicationUserRepository);
Assert.IsTrue(pipeline.Order == 3);
}
}
And those test works fine since for ActionSuccessfullyCompleted and ActionFailingCompleted I substitute the IRetrieveApplicationUserRepository's result with my expected one.
The real implementation of ther repository is
public class RetrieveApplicationUserRepository : IRetrieveApplicationUserRepository
{
#region Variables
private readonly IConfiguration configuration;
#endregion
#region Ctor
public RetrieveApplicationUserRepository(IConfiguration configuration)
{
this.configuration = configuration;
}
#endregion
#region IRetrieveApplicationUserRepository
public async Task<string> GetApplicationUser(IDictionary<string, object> context)
{
if (configuration.AppSettings[Resources.ApplicationUserFromDomainUserKey] == null)
throw new KeyNotFoundException(Resources.ApplicationUserFromDomainUserKey);
if (string.IsNullOrEmpty(configuration.ConnectionString))
throw new NullReferenceException();
string storedProcedure = configuration.AppSettings.Get(Resources.ApplicationUserFromDomainUserKey);
string result;
using (var sqlConnection = new SqlConnection(configuration.ConnectionString))
{
using (var sqlCommand = new SqlCommand(storedProcedure, sqlConnection))
{
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.AddWithValue("#DOMAINUSER", context[Resources.DomainUser]);
sqlCommand.Parameters.AddWithValue("#DOMAIN", context[Resources.DomainName]);
sqlCommand.Parameters.AddWithValue("#APPID", context[Resources.ApplicationId]);
sqlConnection.Open();
result = (string)await sqlCommand.ExecuteScalarAsync();
}
}
if (result == null)
throw new UserMappingNotFoundException();
return result;
}
#endregion
}
Here're the questions :
Are the test I wrote correct?
I've seen using Resharper's Code Coverage that it wants me to test-cover the properties...is there a way I can avoid this? is this test meaningful?
What's your approach when you've to unit test component that're related to DB? Have you got a real-db that's used for test? Consider that the real DB is about 10Gb so I don't want to have a copy as mdf (condider I can have this) just to test a small portion of the DB
Talking with my colleagues they told me to use test just for TDD while I wish to use them to avoid regressions
Going back to the DB question, I don't want to have a test where I write if username is "John" and maybe tomorrow John user won't be present in the DB anymore,so that the test I expect to pass wont' pass anoymore
The usual approach is to isolate the database side with an abstraction, so you can provide a test dummy (mock, fake, etc) of that abstraction. Only test an actual database when you do the integration testing.
For the tests of database stored procedures, you may well want a different test harness, creating a new test database in memory (equivalently, in a RAM-backed filesystem). You only need to populate enough data for the individual test (we're doing functional testing here, not performance testing), and you may be able to retain table structure across tests with judicious use of rollback.
I have done this, but it's some time ago, so I'll refrain from giving examples that may be no longer state-of-the-art (even if the code does still exist, and if I could find it).

How to unit test Service Stacks Redis Client with Moq

I'm trying to understand how can I mock the IRedisClientsManager so that I can unit test the Handle Method below using Moq.
Cheers
public class PropertyCommandHandler : ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult>
{
private readonly IRedisClientsManager _manager;
public PropertyCommandHandler(IRedisClientsManager manager)
{
this._manager = manager;
}
public PropertyCommandResult Handle(PropertySaveRequest request)
{
request.Property.OwnerId.ValidateArgumentRange();
using (var client =_manager.GetClient())
{
var propertyClient = client.As<Model.Property>();
var propertyKey = string.Format("property:{0}", request.Property.OwnerId);
propertyClient.SetEntry(propertyKey, request.Property);
client.AddItemToSet("property", request.Property.OwnerId.ToString());
}
return new PropertyCommandResult() {Success = true};
}
}
Which I call from the service like so
public class PropertyService : Service, IPropertyService
{
private readonly ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult> _commandHandler;
public PropertyService(ICommandHandlerFor<PropertySaveRequest, PropertyCommandResult> commandHandler)
{
this._commandHandler = commandHandler;
}
public object Post(PropertySaveRequest request)
{
if (request.Property == null)
throw new HttpError(HttpStatusCode.BadRequest, "Property cannot be null");
var command = _commandHandler.Handle(request);
return command;
}
}
so far this has been the approach - not sure if on right track
[Test]
public void TestMethod1()
{
//arrange
_container = new WindsorContainer()
.Install(new PropertyInstaller());
var mock = new Mock<IRedisClientsManager>();
var instance = new Mock<RedisClient>();
mock.Setup(t => t.GetClient()).Returns(instance);
// cannot resolve method error on instance
// stuck ...
var service = _container.Resolve<IPropertyService>(mock);
}
In short, since RedisClient implements IRedisClient, did you try to create the mock using the interface?
var instance = new Mock<IRedisClient>();
why are you using a real container for your unit test?
You should use an auto-mocking container or simply (since you are already taking care of the mock manually) create a real instance of your test target supplying mocks as dependencies
var target= new PropertyCommandHandler(mock);
BTW IMHO a "command handler" that returns a value sounds like a smell...