Как сохранить тип возврата метода «void» в F#?

Я пишу модульные тесты для своей библиотеки F#, используя F#, Visual Studio Unit Testing Framework (он же MSTest) и FluentAssertions.

Тестовый метод должен иметь возвращаемый тип либо void, либо Task. В С# это легко:

[TestMethod]
public void TestMethod1()
{
    false.Should().BeFalse();
}

В F# у меня есть следующее:

[<TestMethod>]
member this.TestMethod1() =
    false.Should().BeFalse(null)
    |> ignore

В противном случае тип возвращаемого значения изменяется на FluentAssertions.PrimitivesBooleanAssertions, поэтому Test Runner его не видит.

Как избежать |> ignore в конце каждого теста?


person abatishchev    schedule 12.03.2014    source источник


Ответы (3)


Здесь требуется |> ignore, так как подпись TestMethod1 выводится "изнутри". Учтите, что в C# возвращаемый тип метода требуется в объявлении метода. Это глубокие различия между языками.

API-интерфейсы «Fluent» доставляют неудобства в F#, поскольку они включают методы экземпляра, которые одновременно имеют эффект и возвращают значение, что является красным флагом в F#. То есть, хотя побочные эффекты разрешены в F#, они несколько изолированы как в спецификации языка, так и по соглашению. Ожидается, что метод, возвращающий unit, имеет эффект, но, наоборот, ожидается, что метод, возвращающий неединичное значение, будет чистым.

Кроме того, API-интерфейсы Fluent стремятся устранить ограничения таких языков, как C#, которых нет в F# или которые решаются по-другому. Например, в F# оператор конвейера + преобразования неизменяемой структуры данных сравнимы с плавным API на императивном языке.

Попробуйте использовать более идиоматическую библиотеку утверждений для модульного тестирования F#, например Unquote (отказ от ответственности, я автор). Он использует многие сильные стороны F# так же, как FluentAssertions пытается компенсировать недостатки C#.

person Stephen Swensen    schedule 13.03.2014
comment
Кстати, почему вы использовали Google Code вместо Github или Codeplex? Эти два кажутся мне лучшим хостингом с открытым исходным кодом. - person abatishchev; 16.03.2014
comment
@abatishchev только Google Code поддерживает как Mercurial, так и Subversion (SvnBridge не в счет), мои распределенные и централизованные системы контроля версий. Кроме того, я всегда предпочитал простой, но мощный пользовательский интерфейс Google Code. При этом меня беспокоит недавнее прекращение Google Code бинарного хостинга и общее отсутствие дальнейшего развития. - person Stephen Swensen; 16.03.2014
comment
Рассматривали ли вы тогда bitbucket.org? Не такой причудливый, как GitHub, но поддерживает Hg и в целом работает очень хорошо. - person abatishchev; 18.03.2014
comment
И поддерживает ли Unquote строковые утверждения, как в моем вопросе, то есть ends with? - person abatishchev; 18.03.2014
comment
Я не заглядывал слишком глубоко в bitbucket.org, но навскидку похоже, что он не поддерживает svn (DVCS великолепен и все такое, но я считаю, что CVCS все еще имеет свои сильные стороны). - person Stephen Swensen; 18.03.2014
comment
О да, прелесть Unquote в том, что вы используете регулярные выражения F# в качестве утверждений: захваченные с помощью цитат как AST, Unquote может декомпилировать и постепенно уменьшать их для дружественных сообщений об ошибках. Итак, чтобы утверждать, что строка чем-то заканчивается, вы просто делаете, например. test <@ "my string is good".EndsWith("is good") @> - person Stephen Swensen; 18.03.2014

Просто добавьте () в конце вашей функции

Это вернет единицу

person John Palmer    schedule 13.03.2014
comment
Затем я получаю предупреждение: This expression should have type 'unit', but has type 'AndConstraint<Primitives.PrimitivesBooleanAssertions>'. Use 'ignore' to discard the result of the expression, or 'let' to bind the result to a name. - person abatishchev; 13.03.2014

В F# вместо этого можно попробовать FsUnit.

Вы не можете вернуть void в F#, слава богам! Когда вы используете |> ignore в конце метода, метод возвращает unit. В фа#,

«System.Void» можно использовать только как 'typeof<System.Void>'

person V.B.    schedule 12.03.2014