如何使用F#对C#逻辑进行单元测试

时间:2015-11-09 12:08:32

标签: unit-testing f#

我正在自己学习F#,并试图将一些F#偷偷带进工作场所。 因此,我想在F#中编写单元测试来测试C#逻辑。

有人能为我提供一个简单的F#单元测试示例,该测试针对C#方法并通过练习该方法来验证C#属性吗?

更新 这是一个例子。当为名字和姓氏提供一个值时,我们如何单元测试(在F#中)GetFullName返回名字和姓氏?

namespace MVVMExample
{
    public class ViewModel : INotifyPropertyChanged
    {
        private string _firstName;

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
                RaisePropertyChanged("FirstName");
            }
        }

        private string _lastName;

        public string LastName
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
                RaisePropertyChanged("LastName");
            }
        }

        public string GetFullName()
        {
            return string.Format("{0} {1}", FirstName, LastName);
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

1 个答案:

答案 0 :(得分:3)

因此使用 NUnit 对此ViewModel进行的非常简单的测试可能如下所示:

测试GetFullName

这是对此功能的可能测试:

[<Test>]
member __.``GetFullName = "Jon Doe" if FirstName = "Jon" and LastName = "Doh"``() =
    let vm = ViewModel()
    vm.FirstName <- "Jon"
    vm.LastName <- "Doe"

    Assert.AreEqual("Jon Doe", vm.GetFullName())

测试PropertyChanged

[<TestFixture>]
type ``ViewModel Unit Tests``() = 

    [<Test>]
    member __.``a PropertyChanged event should be raised if the FirstName was changed``() =
        let vm = ViewModel()
        let mutable lastChangedProperty = ""
        vm.PropertyChanged.Add (fun e -> lastChangedProperty <- e.PropertyName)

        vm.FirstName <- "Tom"

        Assert.AreEqual("FirstName", lastChangedProperty)

当然这不是功能但我认为对于给定的问题应该是合理的。

正如您所看到的,它与您对C#测试的期望基本相同 - 我使用的唯一 F#功能``...``中的函数/类名,它使您的输出成为可能试车员看起​​来更好:

ReSharper Testrunner output

代码演练

  • [TestFixture] class Test {...}只是转化为[<TestFixture>] type Test() = ...
  • 一个[Test]方法只是[<Test>] member this.MyTestFunction() = ...this只有在您需要它时 - 正如您所看到的那样我没有这样做我使用了惯用的我 - 不 - 护理 __占位符 - 在F#中查看,您可以按照自己想要的方式命名this - 参考 - 而且您必须在每个班级成员上进行操作。
  • 因为我想在事件被触发时更改lastChangedProperty字符串我将其声明为mutable(因此您可以使用assign运算符<-
  • 添加事件处理程序,您只需在事件
  • 上使用.Add函数即可
  • (fun e -> ..)是一个lambda - 在C#中,这将是e => ...

声明

当然,如果你想在一个WPF应用程序中使用这个viewmodel,你应该确保调度到UI-Thread等,这将使测试更加讨厌但是对于你的例子来说简单的红绿色循环应该有效;)

我希望这可以帮助你(但当然它并没有真正显示F#的优点,因为这里的测试是丑陋的副作用)