F #: как на самом деле инициализировать переменные, определенные над тестовой функцией XUnit, при запуске теста? - PullRequest
2 голосов
/ 07 июня 2019

В ответ на еще один вопрос: F #: почему эти две коллекции не равны? В приведенном ниже примере показано, что при выполнении Open an account... test id и contact не инициализируются.

Если бы были функции, возвращающие те же значения и вызываемые в теле теста, это бы сработало.

Мне интересно, почему это так, и если есть что-то, что я могу сделать, чтобы эти переменные правильно инициализировались во время выполнения теста.

let id = Guid.Empty
let contact = {
    Name = {
        FirstName = "Marcel"
        MiddleInitial = None
        LastName = "Patulacci"
    }
    DateOfBith = new DateTime(1850, 12, 25)
    Address = {
        Address1 = "41 av 8 Mai 1945"
        Address2 = None
        City = "Sarcelles"
        State = None
        Zip = "95200"
    }
    PhoneNumber = {
        DialOutCode = 33
        LocalNumber = "766030703"
    }
    Email = "marcel.patulacci@outlook.com"
}

[<Fact>]
let ``Open an account...``() =
    let event = Event.AccountOpened({
        AccountId = id
        Contact = contact
    })

    let a = [event]
    let b = seq { yield event }

    Assert.Equal(a, b)

1 Ответ

3 голосов
/ 07 июня 2019

Это связано с тем, как модули F # реализованы в .NET IL. Модули компилируются в статические классы, а значения, определенные модулями, инициализируются в статическом конструкторе класса. Но из-за того, как XUnit загружает тесты, статический конструктор не запускается.

Возможный способ обойти это - использовать класс вместо модуля, поскольку XUnit запускает конструкторы instance . let функции в классе скомпилированы с закрытыми методами, поэтому тесты распознаются XUnit без необходимости переключения на синтаксис member.

type MyTests() =

    let id = Guid.Empty
    let contact = // ...

    [<Fact>]
    let ``Open an account...``() =
        // ...
...