Moq覆盖以前的设置?

时间:2014-02-04 22:15:10

标签: c# parameters nunit override moq

您好我正在尝试使用两个可能的输入来设置类的方法的模拟。当我检查输出时,只有最后一次设置返回预期输出。第一个没有。非常感谢任何帮助。

[Test]
public void ClimbOnceTwoNeighbour_Sample()
{
    stateConverter = new Mock<StateConverter>();

    solution = new Mock<Solution>();
    state = new Mock<State>();

    var neightbourSolution1 = new Mock<Solution>();
    var neighbourState1 = new Mock<State>();
    var neightbourSolution2 = new Mock<Solution>();
    var neighbourState2 = new Mock<State>();

    stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
    stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);

    var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);//return null ????
    var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);//return neighbourState2.Object)


    Assert.AreEqual(neighbourState2.Object, state2);//pass test here
    Assert.AreEqual(neighbourState1.Object, state1);//fail here due to null is returned from previous statement

}

3 个答案:

答案 0 :(得分:0)

我复制了你的代码片段并创建了空类以使其编译。它按预期工作。请试一试,让我知道结果是什么。

以下是代码:

using Moq;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        var stateConverter = new Mock<StateConverter>();

        var solution = new Mock<Solution>();
        var state = new Mock<State>();

        var neightbourSolution1 = new Mock<Solution>();
        var neighbourState1 = new Mock<State>();
        var neightbourSolution2 = new Mock<Solution>();
        var neighbourState2 = new Mock<State>();

        stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
        stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);

        var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);
        var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);
    }
}

public class State{}

public class Solution{}

public abstract class StateConverter
{
    public abstract State FromSolution(Solution p0, State isAny);
}

}

答案 1 :(得分:0)

我使用Moq的一个习惯是使用完整的It.Is(o =&gt; o == object)语法来避免在设置可能含糊不清或隐含时出现任何问题。可能是Moq只是简单地将对象放在设置中并覆盖它已经存在的任何其他对象。

stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);

然后看起来像

stateConverter.Setup(x => x.FromSolution(It.Is<Solution>(solution => solution == neightbourSolution1.Object), It.IsAny<State>())).Returns(neighbourState1.Object);
stateConverter.Setup(x => x.FromSolution(It.Is<Solution>(solution => solution == neightbourSolution2.Object), It.IsAny<State>())).Returns(neighbourState2.Object);

我不太确定这是否可以解决你的问题,因为隐含性非常清楚。 :/

答案 2 :(得分:0)

你尝试过这样的事吗?

[Test]
public void ClimbOnceTwoNeighbour_Sample()
{
    stateConverter = new Mock<StateConverter>();

    solution = new Mock<Solution>();
    state = new Mock<State>();

    var neightbourSolution1 = new Mock<Solution>();
    var neighbourState1 = new Mock<State>();
    var neightbourSolution2 = new Mock<Solution>();
    var neighbourState2 = new Mock<State>();

    stateConverter.Setup(x => x.FromSolution(neightbourSolution1.Object, It.IsAny<State>())).Returns(neighbourState1.Object);
var state1 = stateConverter.Object.FromSolution(neightbourSolution1.Object, state.Object);//return null ????


    stateConverter.Setup(x => x.FromSolution(neightbourSolution2.Object, It.IsAny<State>())).Returns(neighbourState2.Object);
    var state2 = stateConverter.Object.FromSolution(neightbourSolution2.Object, state.Object);//return neighbourState2.Object)


    Assert.AreEqual(neighbourState2.Object, state2);//pass test here
    Assert.AreEqual(neighbourState1.Object, state1);//fail here due to null is returned from previous statement

}

我认为这样,当您向state1分配第一次返回的结果时,可以再次使用安装程序并将结果添加到state2;)