我将最常创建的模拟转移到扩展和帮助器类中,以便能够在多个测试中重用它们。事实证明,它们显然是上下文相关的,而坐在其他地方却不起作用。
此代码演示了该问题:
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; }
}
有没有办法使封装在其他类中的JustMock
代码也能正常工作?
答案 0 :(得分:1)
这里的问题是您正在使用静态MockFactory,并且当您直接非静态使用它时,它可以工作。如果每次还是每次重新创建模拟时仍在初始化测试数据,为什么要使用静态类?尝试使用此方法创建一个基础测试类,并将其命名为base.YourInitialiseMethod()或类似TestFixtures的东西。如果您查看JustMock的文档,它们总是会在每个测试用例中单独创建。
答案 1 :(得分:0)
我发现了一个把戏。您可以使用static
将其拉到相同的Func
上下文中。 ReturnsTask
仍然不会合作,但至少在总体安排上会合作。
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;
};
}
}
}
我把另一个扩展转了过来,
public static Task<T> ToTask<T>(this T obj) => Task.FromResult(obj);
然后我打电话给
.Returns(new[] { new User { Name = "John" } }.ToTask())