Reputation: 18655
I moved the most frequently created mocks into extensions and helper classes to be able to reuse them in several tests. I was very surprised when it turned out that they are appently context dependent and don't work when sitting elsewhere.
This code demonstrates the issue:
void Main()
{
// Does not get the mock user.
var db = MockFactory.MockUserDatabase();
db.GetUsersAsync().GetAwaiter().GetResult().Dump(); // <-- null
// This works and gets the mock user.
var mock = Mock.Create<IUserDatabase>();
mock
.Arrange(x => x.GetUsersAsync())
.Returns(Task.FromResult(new[] { new User { Name = "John" } }));
mock.GetUsersAsync().GetAwaiter().GetResult().Dump(); // <-- mock user
}
static class MockFactory
{
public static IUserDatabase MockUserDatabase()
{
var mock = Mock.Create<IUserDatabase>();
mock
.Arrange(x => x.GetUsersAsync())
.ReturnsTask(new[] { new User { Name = "John" } });
return mock;
}
}
public static class JustMockHelpers
{
public static IAssertable ReturnsTask<TReturn>(this IAssertable assertable, TReturn value)
{
return assertable.Returns(Task.FromResult<TReturn>(value));
}
}
public interface IUserDatabase
{
Task<User[]> GetUsersAsync();
}
public class User
{
public string Name { get; set; }
}
Is there any way I can make the JustMock
code encapsulated in other classes work too?
Upvotes: 1
Views: 156
Reputation: 18655
I have found a trick. You can pull it to the same static
context with a Func
. ReturnsTask
still won't cooperate but at least the general arrangement does.
static class MockFactory
{
public static Func<IUserDatabase> MockUserDatabase
{
get
{
return () =>
{
var mock = Mock.Create<IUserDatabase>();
mock
.Arrange(x => x.GetUsersAsync())
.Returns(new[] { new User { Name = "John" } }.ToTask());
return mock;
};
}
}
}
I turned the other extension around and made it:
public static Task<T> ToTask<T>(this T obj) => Task.FromResult(obj);
Then I just call:
.Returns(new[] { new User { Name = "John" } }.ToTask())
Upvotes: 0
Reputation: 1547
The problem here is you are using a Static MockFactory and it works when you use it directly not statically. Why Would use a static class if you are still initiating the test data each time and each time you recreate the mock? Either try to have a base testing class with this method and call it base.YourInitialiseMethod() or something like TestFixtures. If you look at documentation of JustMock they always do create inside each test case individually.
Upvotes: 1