Модульное тестирование параллельной функции с использованием moq - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть базовый интерфейс и класс, который принимает его реализацию в конструкторе, затем выбирает некоторые данные последовательно или параллельно в зависимости от ввода.

    public interface ISomeService
    {
        List<int> FetchSomeData(int a);
    }      

    public class SomeClass
    {
        private ISomeService sr { get; }

        public SomeClass(ISomeService sr) => this.sr = sr;

        public int DoMagic(bool paralell)
        {
            int sum = 0;
            if (paralell)
            {
                Parallel.For(0, 10, (x) =>
                {
                    sum += sr.FetchSomeData(x).Sum(z => z);
                });
            }
            else
            {
                for (int i = 0; i < 10; i++)
                {
                    sum += sr.FetchSomeData(i).Sum(z => z);
                }
            }
            return sum;
        }
    }

, затем у меня есть тест:

    [Test]
    public void DoTest()
    {

        var service = new Mock<ISomeService>(MockBehavior.Strict);
        service.Setup(x => x.FetchSomeData(It.IsAny<int>()))
            .Returns(() => new List<int> { 3 });

        var someClass = new SomeClass(service.Object);

        var notParallel = someClass.DoMagic(false);

        var parallel = someClass.DoMagic(true);

        Assert.AreEqual(30, notParallel);

        Assert.AreEqual(30, parallel);
    }

И проблема:

NotParallel результаты всегда одинаковы (30), но в параллельном случае результаты различаются (иногда 15, другой раз 21 и т. Д.).В чем может быть проблема?Как это решить?

1 Ответ

0 голосов
/ 19 ноября 2018

Вы обновляете переменную sum из нескольких потоков. Вот несколько вариантов, как сделать этот потокобезопасным: https://social.msdn.microsoft.com/Forums/vstudio/en-US/d87c1085-cacb-4d82-826f-4151bf967f86/parallelfor-with-sum?forum=parallelextensions

...