c# - 断言表达式

时间:2014-11-12 18:11:37

标签: c# unit-testing nunit

我有一个'示例'类,我想为它创建单元测试。看看我的课程:

public class Example 
{
    private readonly Calculator _calculator;

    public Example(ICalculator calculator)
    {
        _calculator = calculator;
    }

    public void Calculate()
    {
        _calculator.Execute(operation => operation.Subtract());
    }
}

public interface IOperation { 
    void Sum();
    void Subtract();
}

public inferface ICalculator { 
    void Execute(Action<IOperation> action);
}

public class Calculator {
    public void Execute(Action<IOperation> action){}
}

我想要的是创建一个单元测试类来验证示例类Calculate中的方法是否调用_calculator.Execute作为参数传递operation.Subtract()。有可能吗?

我知道如何模拟我的ICalculator并验证Execute是否被调用一次,但我不知道如何使用Execute作为参数调用operation.Subtract()方法而不是operation.Sum()

我正在使用NUnit来创建单元测试。在这里,您可以看到我的单元测试课程目前的情况:

[TestFixture]
public class ExampleTests 
{
    [Test]
    public void Test1()
    {
        var calculator = new Mock<ICalculator>();
        var subject = new Example(calculator.Object);

        subject.Calculate();

        calculator.Verify(x => x.Execute(It.IsAny<Action<IOperation>>()), Times.Once);
    }
}

希望有人能理解我的英语,对此感到抱歉。

2 个答案:

答案 0 :(得分:0)

您正在将匿名委托operation => operation.Subtract()传递给_calculator.Execute - 因此您在以后断言参数时无法构建它。

你可以这样做:

    public class Example 
    {
        private readonly ICalculator _calculator;

        public Example(ICalculator calculator)
        {
            _calculator = calculator;
        }

        public Action<IOperation> Subtract = op => op.Subtract();

        public Action<IOperation> Add = op => op.Sum();

        public void Calculate()
        {
            _calculator.Execute(Subtract);
        }
    }

并断言如此(省略第二个参数默认为一次):

calculator.Verify(x => x.Execute(subject.Subtract));

然而,为了能够编写测试,这看起来像是错综复杂的设计。

答案 1 :(得分:0)

你不能直接验证传递了什么lambda但你可以通过实际调用所述lambda与另一个模拟器来解决这个问题:

var calculator = new Mock<ICalculator>();
var operation = new Mock<IOperation>();
// when calculator's Execute is called, invoke it's argument (Action<IOperation>)
// with mocked IOperation which will later be verified
calculator
    .Setup(c => c.Execute(It.IsAny<Action<IOperation>>()))
    .Callback<Action<IOperation>>(args => args(operation.Object));
var example = new Example(calculator.Object);

example.Calculate();

calculator.Verify(c => c.Execute(It.IsAny<Action<IOperation>>()));
operation.Verify(o => o.Subtract());