2010-01-21 4 views
0

Мои модульные тесты делают что-то очень странное, когда я вызываю метод базового базового типа. Я пробовал как NUnit, так и MSTest с тем же результатом. Так организован код:IEnumerable и доходность возврата

public class MyStub {} 

public class EnumerableGenerator 
{ 
    public bool GotMyStubs; 

    public IEnumerable<MyStub> GetMyStubs() 
    { 
     GotMyStubs = true; 
     yield return new MyStub(); 
    } 
} 
public class ConsoleRunner 
{ 
public void Main(string args[]) 
{ 
    EnumerableGenerator gen = new EnumerableGenerator(); 
    gen.GotMyStubs = false; 
    var myStubs = gen.GetMyStubs(); 
    if (!gen.GotMyStubs) 
     return 1; 
} 
} 

Тест не проходит очевидно. Странная часть заключается в том, что код отлично работает, когда я тестирую интеграцию. Он только ломается в модульном тесте. Я вообще не могу войти в GetMyStubs. Точки разрыва внутри метода также не ломаются. Я включил брейк для всех исключений, которые бросает CLR, и это тоже ничего не дает.

Я исследовал тип, возвращаемый GetMyStubs и полное имя типа выглядит следующим образом:

[MyNamespace.EnumerableGenerator2 + <GetMyStubs> d__8 [[MyNamespace.MyStub, MyNamespace, Version = 7.1.0.0, культура = нейтральной, PublicKeyToken = null]]

Теперь, когда я смотрю номера моего кода покрытия (через MSTest), я замечаю, что есть запись EnumerableGenerator.d__8.

Кто-нибудь видел что-то подобное? Я полностью потерян ....

+0

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

+0

Правильно - да, это определенно объясняет, почему он терпит неудачу. –

+0

Я получаю это довольно часто. Вот мои статьи на нем: http://blogs.msdn.com/ericlippert/archive/2007/09/05/psychic-debugging-part-one.aspx и HTTP: //blogs.msdn .com/ericlippert/archive/2007/09/06/psychic-debugging-part-two.aspx –

ответ

3

Код, который вы указали, даже не компилируется - на IEnumerable<T> нет собственности Count. Есть Count()метод расширения - это то, что вы имели в виду?

Я сильно подозреваю, что MyMethod() не действительно тоже выглядит так. Я подозреваю, что на самом деле он использует yield return для возврата элементов ... в этот момент будет иметь смысл полное имя этого типа, поскольку это машина состояний, сгенерированная для вас блоком итератора.

Предполагая, что это так, когда вы звоните MyMethod(), который не будет выполнять какой-либо из ваших кодов. Он создаст машину состояний и вернет ее. Когда вы начнете повторять его, затем, он начнет выполнять ваш код ... и именно тогда я ожидаю, что брейк-очки будут удалены.

Не могли бы вы предоставить короткий, но полный пример (при необходимости, используя NUnit, но консольное приложение было бы идеальным) из-за этого?

+0

Yup вы были правы относительно метода расширения. Вот что я имел в виду. И снова вы были правы в возвращении урожая. Я определенно узнал что-то об этом сегодня. Я обновлю пример выше, чтобы более четко проиллюстрировать код. –