Проблемы FakeItEasy VB.NET с параметрами

Хорошо, я пытаюсь научиться тестировать с использованием фиктивной среды, и я работаю в VB.NET, я новичок в лямбда-выражениях, и все мои предыдущие приложения были написаны в версии 2005 или ранее. Теперь у меня 2010 год. Поэтому я попробовал Rhino.Mocks, но мне было трудно понять это, в основном из-за старого синтаксиса. Поскольку в наши дни никто не ведет блоги в VB.NET, я просматривал примеры C# и пытался понять, что происходит.

Итак, у меня есть ситуация, когда я передаю интерфейс конструктору класса и сохраняю ссылку на этот интерфейс. Когда метод вызывается для объекта и возникает событие, которое должно обрабатываться классом, реализующим интерфейс.

У меня возникли проблемы, поэтому я попытался создать простую версию на C# и повторить шаги в vb.net.

Итак, мой интерфейс:

public interface IBroadcastClient
{
   void MessageReceivedHandler(string msg);
}

Класс, который вызывает события:

public class Broadcaster
{     
    public Broadcaster(IBroadcastClient c)
    {
        _client= c;
        this.SendMessage += new MessageReceived(_client.MessageReceivedHandler);
    }
    private IBroadcastClient _client;


    public event MessageReceived SendMessage;

    public void SendMessageNow()
    {
        string _Message;
        if (SendMessage != null)
        {
            _Message = @"Yay!";
            SendMessage(_Message);
        }
    }
}

Тест:

[TestMethod]
public void TestSendMessageWithIgnoreParameter()
{
    //string msg = @"Yay!";
    var client = A.Fake<IBroadcastClient>();
    Broadcaster b = new Broadcaster(client);
    b.SendMessageNow();
    A.CallTo(() => client.MessageReceivedHandler(A<string>.Ignored)).MustHaveHappened();
}

Это проходит, пока проблем нет.

Теперь попробуйте то же самое в vb.net; Тот же интерфейс и класс вещателя, только на vb.net, а не на C#, с исходным юнит-тестом.

<TestMethod()>
Public Sub TestMethod1()
    Dim client = A.Fake(Of IBroadcastClient)()
    Dim b As New Broadcaster(client)
    b.SendMessageNow()
    NextCall.To(client).MustHaveHappened()
    client.MessageReceivedHandler(A(Of String).Ignored)

End Sub

Это не удается со следующим сообщением об ошибке; "Утверждение не выполнено для следующего вызова: TestFakeItEasyVB.IBroadcastClient.MessageReceivedHandler(msg:) Ожидалось, что он будет найден хотя бы один раз, но найден #0 раз среди вызовов: 1: TestFakeItEasyVB.IBroadcastClient.MessageReceivedHandler(msg: "Yay!")"

Как ни странно писать это таким образом;

<TestMethod()>
Public Sub TestMethod3()
    Dim client = A.Fake(Of IBroadcastClient)()
    Dim b As New Broadcaster(client)
    b.SendMessageNow()
    A.CallTo(Sub() client.MessageReceivedHandler(A(Of String).Ignored)).MustNotHaveHappened()


End Sub

Также произойдет сбой с тем же сообщением об ошибке, однако эта версия теста пройдена.

<TestMethod()>
Public Sub TestMethod2()
    Dim client = A.Fake(Of IBroadcastClient)()
    Dim b As New Broadcaster(client)
    b.SendMessageNow()
    NextCall.To(client).MustHaveHappened()
    client.MessageReceivedHandler("Yay!")

End Sub

Этот вариант также проходит в C #, моя проблема заключается в том, что я делаю неправильно, чтобы тест игнорировал аргумент, переданный фальшивому обработчику событий?


person Joe    schedule 15.04.2011    source источник
comment
В вашем TestMethod3 вы указываете MustNotHaveHappened, но в других тестах у вас есть MustHaveHappened, я думаю, это ошибка, верно?   -  person Patrik Hägne    schedule 16.04.2011


Ответы (1)


Синтаксис NextCall существует по устаревшим причинам, лучше использовать синтаксис выражения:

A.CallTo(Sub() client.MessageReceivedHandler(A(Of String).Ignored)).MustNotHaveHappened()

В ваших тестах выше всех остальных есть MustHaveHappened, но этот конкретный имеет MustNotHaveHappened, я думаю, поэтому ваш тест терпит неудачу. Я скомпилировал ваш код и запустил его, и как только он изменится на MustHaveHappened, тест пройден.

В настоящее время вы не можете использовать ограничения аргументов в специфичном для VB синтаксисе NextCall. Однако вы можете использовать метод WhenArgumentsMatch, чтобы переписать свой первый тест следующим образом:

<TestMethod()>
Public Sub TestMethod1()
    Dim client = A.Fake(Of IBroadcastClient)()
    Dim b As New Broadcaster(client)
    b.SendMessageNow()
    NextCall.To(client).WhenArgumentsMatch(Function(a) a.Get(Of String)(0) = "Yay!").MustHaveHappened()

    client.MessageReceivedHandler(Nothing)
End Sub

Или вы можете использовать расширение «WithAnyArguments», чтобы игнорировать все аргументы:

<TestMethod()>
Public Sub TestMethod1()
    Dim client = A.Fake(Of IBroadcastClient)()
    Dim b As New Broadcaster(client)
    b.SendMessageNow()
    NextCall.To(client).WithAnyArguments().MustHaveHappened()

    client.MessageReceivedHandler(Nothing)
End Sub
person Patrik Hägne    schedule 16.04.2011
comment
Спасибо. Еще одна вещь: .WithAnyArguments отличается от (Of ‹type›.Ignored)? Я вижу, что .WithNayArguments делает тест более четким. - person Joe; 17.04.2011
comment
Разница в том, что у вас много аргументов, и вы хотите игнорировать их все. - person Patrik Hägne; 17.04.2011