Помощники JustMock в другом классе возвращают null в тесте - PullRequest
0 голосов
/ 11 июля 2019

Я переместил наиболее часто создаваемые макеты в расширения и вспомогательные классы, чтобы иметь возможность использовать их в нескольких тестах. Я был очень удивлен, когда выяснилось, что они зависят от контекста и не работают, когда сидят в другом месте.

Этот код демонстрирует проблему:

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 код, инкапсулированный в других классах?

Ответы [ 2 ]

1 голос
/ 11 июля 2019

Проблема здесь в том, что вы используете Static MockFactory, и он работает, когда вы используете его напрямую, а не статически.Зачем использовать статический класс, если вы все еще инициируете тестовые данные каждый раз и каждый раз, когда создаете макет заново?Либо попробуйте создать базовый класс тестирования с этим методом и назовите его base.YourInitialiseMethod (), либо что-то вроде TestFixtures.Если вы посмотрите на документацию JustMock, они всегда создаются внутри каждого тестового примера в отдельности.

0 голосов
/ 11 июля 2019

Я нашел трюк. Вы можете вытянуть его в тот же 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())
...