这使我花了半天时间进行调试和调试。我正在使用Moq 4.2.1408.0717。 我有一个被嘲笑的服务。然后,我有了再次被嘲笑的客户端,但是match属性之一将使用(模拟的)服务进行评估。 简化的示例如下:
[TestFixture]
class PPAP
{
[Test]
public void Test_Apple_Pen()
{
var fruitMock = new Mock<IFruit>(); // the mocked service
fruitMock.Setup(x => x.GetFruit()).Returns("apple");
var fw = new FruitWrapper(fruitMock.Object); // object that uses the (mocked) service behind curtains
var uhhMock = new Mock<IUhh>();
uhhMock.Setup(x => x.Uhh(fw.GetFruit())).Returns("apple-pen");
// Utterly unimportant part below, added for clarity:
var result = uhhMock.Object.Uhh("apple");
Assert.That(result, Is.EqualTo("apple-pen"));
}
}
public interface IFruit
{
string GetFruit();
}
public interface IUhh
{
string Uhh(string s);
}
public class FruitWrapper
{
private IFruit _fruit;
public FruitWrapper(IFruit fruit)
{
_fruit = fruit;
}
public string GetFruit()
{
var f = _fruit.GetFruit(); // f should never be null since I mocked it already!
// LOOK HERE *jumps and waves* THIS IS THE PROBLEM:
if (f == null) {
throw new Exception("POINT OF THE QUESTION HERE: Service mock doesn't function!!!");
}
return f; // yet this method will be called twice with f being null before finally called with f == "apple" during Setup()
}
}
问题是,使用服务的代码(示例中为FruitWrapper)没有准备好从服务接收null(毕竟,这是模拟服务的关键!)。尽管如此,在客户端模拟程序的Setup()(在示例中为uhhMock)期间,将调用FruitWrapper的GetFruit(),以便服务将返回null(尽管模拟程序已经就绪)。 这是一个例外,这杀死了我的测试。我仍然不知道为什么会这样。这是正常现象还是Moq错误?
(现在,使用简化的示例,测试不会因服务失效而失效,我看到最终对match参数进行了正确评估。)编辑:修改了示例以使其不存在null从服务。如果确实如此,那么最终将有一个服务返回非空的调用。
(当然,如果我将参数(fw.GetFruit())保存到安装程序之前的变量中并在内部使用它,那一切都很好。)
编辑:由于人们难以理解我的意思。我添加了一些代码:
答案 0 :(得分:0)
我不确定您的测试应该做什么。它是一个完整的测试吗?
<p>Click the button to create a SELECT and an OPTION element.</p>
<button onclick="createSelect()">Try it</button>
更改此项以使用您要设置的实际值:
var uhhMock = new Mock<IUhh>();
uhhMock.Setup(x => x.Uhh(fw.GetFruit())).Returns("apple-pen");
另一个问题是,您似乎正在对多层模拟进行某种集成测试(使用模拟var uhhMock = new Mock<IUhh>();
uhhMock.Setup(x => x.Uhh("apple")).Returns("apple-pen");
从具有模拟{{ 1}})。尝试将其分解为使用带有模拟依赖项的被测类。
一个好主意是使用AAA(排列,行为,声明)模式。例如:
IUhh