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

Опитвам се да използвам командата yield, за да актуализирам някои методи, но се натъквам на проблем, който не разбирам. Има известна логика в този метод (проверка за тип null), ако случаят е такъв, тогава пиша в журнал и прекъсвам добива. Което прави точно това, което искам, но в моя модулен тест се казва, че функцията за журнал никога не е била извикана. Добре съм да не влизам в тази ситуация, но искам да знам защо не мога или дали правя нещо нередно.

Ето кода:

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