Reputation: 3068
I have the following repository:
public class WorkspaceRepo : IWorkspacesRepo
{
private readonly ApplicationContext _applicationContext;
public WorkspaceRepo(ApplicationContext applicationContext)
{
_applicationContext = applicationContext;
}
public IEnumerable<Workspace> Workspaces => _applicationContext.Workspaces;
public void Save(Workspace workspace)
{
_applicationContext.Workspaces.Add(workspace);
_applicationContext.SaveChanges();
}
}
And the following method is from my business logic class. I need to test this method:
public Workspace CreateWorkspace(Workspace workspace)
{
if (string.IsNullOrEmpty(workspace.UserUuid))
{
throw new RpcException(new Status(StatusCode.NotFound, "Empty user Uuid"));
}
var freSlots = 10 - _workspacesRepo.Workspaces.Count(x => x.UserUuid == workspace.UserUuid);
if (freSlots <= 0)
{
throw new RpcException(new Status(StatusCode.Aborted, "There are no free slots work workspaces"));
}
_workspacesRepo.Save(workspace);
return workspace;
}
The business logic is simple. I can save only 10 Workspace
object. The next saving must give me RpcException
. Now I would like to test it. Here is the test code:
[Test]
public void User_Cant_Exceed_Workspaces_Limit()
{
// organization
Mock<IWorkspacesRepo> mock = new Mock<IWorkspacesRepo>();
mock.Setup(m => m.Save(It.IsAny<Workspace>())).Callback( /* what to do here?*/ )
var target = new WorkspaceBusinessService(mock.Object, null);
for (var i = 0; i < 10; i++)
{
target.CreateWorkspace(new Workspace
{
Name = Guid.NewGuid().ToString(),
UserUuid = Guid.NewGuid().ToString(),
WorkspaceId = i + 1
});
}
var redundantWorkspace = new Workspace
{
Name = Guid.NewGuid().ToString(),
UserUuid = Guid.NewGuid().ToString(),
WorkspaceId = 11
};
// action
// asserts
var ex = Assert.Throws<RpcException>(() => target.CreateWorkspace(redundantWorkspace));
Assert.That(ex.Message, Is.EqualTo("Status(StatusCode.Aborted, \"There are no free slots work workspaces\")"));
}
But expected behavior is not going on. I watched this with debug and in the CreateWorkspace
method I have always 10 freeSlots
. How to test this situation?
Upvotes: 1
Views: 814
Reputation: 247108
Based on the Logic in the method under test, you are mocking the wrong member.
Mock Workspaces
property so that it behaves as expected when
//..
var freSlots = 10 - _workspacesRepo.Workspaces.Count(x => x.UserUuid == workspace.UserUuid);
if (freSlots <= 0) {
//...
is invoked.
For example
// Arrange
//need common user id
var userUuid = Guid.NewGuid().ToString();
//create workspaces to satisfy Linq Count(Expression)
var workspaces = Enumerable.Range(0, 10).Select(i => new Workspace {
Name = Guid.NewGuid().ToString(),
UserUuid = userUuid, //<-- Note the common user id
WorkspaceId = i + 1
});
Mock<IWorkspacesRepo> mock = new Mock<IWorkspacesRepo>();
//set up the property to return the list
mock.Setup(_ => _.Workspaces).Returns(workspaces);
var target = new WorkspaceBusinessService(mock.Object, null);
var redundantWorkspace = new Workspace {
Name = Guid.NewGuid().ToString(),
UserUuid = userUuid, //<-- Note the common user id
WorkspaceId = 11
};
// Act
Action act = () => target.CreateWorkspace(redundantWorkspace);
//Assert
var ex = Assert.Throws<RpcException>(act);
Assert.That(ex.Message, Is.EqualTo("Status(StatusCode.Aborted, \"There are no free slots work workspaces\")"));
Upvotes: 2