3

我正在尝试解决菱形 kata,以便学习如何使用 fscheck 库编写基于属性的测试。我想用 C# 编写测试,我正在使用 Visual Studio 2017。

我想编写一个基于属性的测试,它不会生成任何随机字符作为输入,而只会生成字母。我不确定如何编写生成器 fscheck 需要执行此操作以及将代码放在哪个文件中?

我到处搜索并阅读文档,但遇到了麻烦(部分原因是我不能很好地将 F# 翻译成 C#)。

如何[Property]用于将输入数据限制为仅字母?

如果有更好的方法请告诉我。

[编辑:]

我编辑了我的代码示例,现在包含 Kurt Schelfthout 的一个工作解决方案。



测试

using DiamondKata;
using FsCheck;
using FsCheck.Xunit;
using Xunit;

namespace DiamondKataTests
{
    public static class Arbitraries
    {
        private static readonly string upperAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        private static readonly string lowerAlphabet = ""; //upperAlphabet.ToLower();
        private static readonly char[] wholeAlphabet = (lowerAlphabet + upperAlphabet).ToCharArray();
        public static Arbitrary<char> LetterGenerator()
        {
            return Gen.Elements(wholeAlphabet).ToArbitrary();
        }
    }

    public class DiamondKataTests
    {
        // THIS WORKS and is apparently the preferred way of doing things
        // also see here: https://stackoverflow.com/questions/32811322/fscheck-in-c-generate-a-list-of-two-dimension-arrays-with-the-same-shape
        [Property()]
        public Property shouldReturnStringAssumesValidCharWasProvided()
        {
            return Prop.ForAll(Arbitraries.LetterGenerator(), letter =>

                // test here
                Assert.NotNull(Diamond.Create(letter))
            );
        }

        // Second solution ...
        // Error here: Arbitraries is a type not valid in the given context
        [Property(Arbitrary = new[] { typeof<Arbitraries> })]
        public void testThatAssumesValidCharWasProvided(char lettersOnlyHERE)
        {
            // ?
        }
    }
}

测试类

namespace DiamondKata
{
    public class Diamond
    {
        public static string Create(char turningPointCharacter)
        {
            return "";
        }
    }
}
4

1 回答 1

3

您不能在属性中设置约束,您可以传递给属性的类型仅限于此。

你有几个选择。您可以为 定义一个自定义Arbitrary实例char,即实现Arbitrary<char>并配置该属性以使用它。

public static class Arbitraries
{
    public static Arbitrary<char> LetterGenerator()
    {
        return Gen.Elements(wholeAlphabet).ToArbitrary();
    }
}

public class DiamondKataTestClass1
{
    [Property(Arbitrary=new[] { typeof<Arbitraries> })]
    public void testThatAssumesValidCharWasProvided(char lettersOnlyHERE)
    {
        // ?
    }
}

您还可以使用更灵活的 API 内联自定义生成器:

public class DiamondKataTestClass1
{
    [Property()]
    public Property testThatAssumesValidCharWasProvided()
    {
        Prop.ForAll(Arbitraries.LetterGenerator()) (letter =>
        // test here
        )
    }
}
于 2017-10-21T11:26:13.863 回答