Добавление логики в метод с помощью yield

Я пытаюсь использовать команду yield для обновления некоторых методов, но столкнулся с проблемой, которую не понимаю. В этом методе есть некоторая логика (проверка типа null), если это так, то я пишу в лог и выдаю break. Что делает именно то, что я хочу, однако в моем модульном тесте говорится, что функция журнала никогда не вызывалась. Я согласен не входить в эту ситуацию, но я хочу знать, почему я не могу или я делаю что-то не так.

Вот код:

public IEnumerable<Ixxx> GetTypes(Type type)
    {
        if (type == null)
        {
            log.WriteRecord("log error", "LogName", true);
            yield break;
        }

        lock (blockingObject)
        {
            foreach (Ixxx item in aDictionary.Values)
            {
                if (item.Type.Name == type.Name)
                {
                    yield return item;
                }
            }
        }
    }

Неудачный модульный тест требует log.WriteRecord никогда не вызывался. Вот этот модульный тест:

[TestMethod]
    public void TestMethod()
    {
        // Arrange
        mockLog.Setup(a => a.WriteRecord(It.IsAny<string>(), It.IsAny<string>(), true)).Returns(true);

        // Act
        sut.GetTypes(null);

        // Assert
        mockLog.Verify(a => a.WriteRecord(It.IsAny<string>(), It.IsAny<string>(), true), Times.Once());
    }

Когда я делал локальную копию (список), этот тест прошел, однако теперь, когда я использую yield, кажется, что я не могу выполнять какие-либо вызовы функций в этом методе? Спасибо за любую помощь!


person ShaffDaddy    schedule 12.03.2015    source источник
comment
Ваша установка предназначена для перегрузки WriteRecord(string, string, true), но в вашем методе вы вызываете перегрузку WriteRecord(string). Вы изменили перегрузку, которую вызывали, когда добавляли yield?   -  person juharr    schedule 12.03.2015
comment
Кроме того, вам необходимо сделать настройку проверяемой с помощью mockLog.Setup(a => ...).Returns(true).Verifiable();   -  person Erik    schedule 12.03.2015
comment
Использование блокировки, которая содержит доходность, чрезвычайно опасно и может легко привести к мертвой блокировке stackoverflow.com/questions/4608215/   -  person John Taylor    schedule 12.03.2015
comment
Макет в порядке, это беспорядок с моей стороны. Я пытался сделать так, чтобы в нем было меньше «конфиденциальной» информации, поэтому я удалил некоторые параметры, забыв, что они нужны. Извините за путаницу   -  person ShaffDaddy    schedule 12.03.2015
comment
Также спасибо за внимание к замку, я не был уверен, какой побочный эффект будет иметь выход на этом   -  person ShaffDaddy    schedule 12.03.2015
comment
Тогда я застрял, создавая локальный список и добавляя к нему, так как мой словарь должен быть потокобезопасным?   -  person ShaffDaddy    schedule 12.03.2015
comment
Возможно, вы сможете использовать ConcurrentDictionary и избежать блокировки. Вы можете безопасно перебирать словарь, и он не вызовет никаких исключений, если он изменится во время перечисления. Эффективно разобраться с использованием ConcurrentDictionary может быть немного сложно.   -  person OldFart    schedule 13.03.2015


Ответы (1)


Строка «sut.GetTypes(null)» просто возвращает IEnumerable, который вы выбрасываете. Поскольку вы никогда не перебираете перечисляемое, ни один код в GetTypes никогда не выполняется.

Попробуйте это вместо этого:

foreach (var x in sut.GetTypes(null)) {}
person OldFart    schedule 12.03.2015
comment
Этот. Люди, использующие ключевые слова, не зная лежащих в их основе концепций... Это называется отложенным выполнением. - person MrDosu; 12.03.2015