【问题标题】:Interface for POCO to test with MoqPOCO 使用 Moq 进行测试的接口
【发布时间】:2020-08-12 13:51:07
【问题描述】:

我们有一个只有属性的类,一个不返回任何东西的测试方法,我们正在使用 Moq 来模拟它的依赖关系。我们想测试是否设置了对象的某些属性。所以我们试图模拟这个类,所以稍后我们将使用 Moq 中的 VerifySet 方法,它抱怨该属性没有被标记为虚拟,也不是一个接口。创建一个接口是可行的,我们可以根据需要验证属性。我们是否应该为所有东西创建一个接口,包括像这样的案例,一个 POCO?

下面我包含一个最小的示例,但实际代码要大得多。

public class Car
{
    public string Id { get; set; }

    public string Name { get; set; }
}

测试

var mock = Mock<ICar>();

handler.Handle(mock);

mock.VerifySet(x=> x.Name = "Furioso");

方法

public void Handle(Car car)
{
    car.Name = "Furioso"
}

界面

public interface ICar
{
    public string Id { get; set; }

    public string Name { get; set; }
}

【问题讨论】:

  • 我个人认为你在这里测试了错误的东西。这对我来说看起来你需要重新考虑你的测试(对不起,我知道这不是一个真正的答案)
  • 您正在测试的类不应该被模拟。模拟类的依赖项(如果有)。如果您这样做,无论在该类中设置什么属性,您都可以在运行您正在测试的任何方法之后在断言步骤中进行检查。你不会嘲笑 POCO。
  • @insane_developer 那么,在不模拟 Car 的情况下,如果方法返回 void,您将如何断言它已按预期修改?

标签: c# oop interface moq


【解决方案1】:

我在这里做出假设,但这是我想要传达的:

var car = new Car(); //no behavior to mock here, just a DTO. You may have to set values to this instance before passing it (or not).

handler.Handle(car); //handler is the instance of the class being tested

//Any other assertions
Assert.Equal("Furioso", car.Name); //I don't use Moq, but whatever is equivalent.

【讨论】:

  • 谢谢,你的回答,和被选中的一样,帮助我记住了一些概念并解决了问题。
【解决方案2】:

在我看来,您想更改 assert 而不是检查 setter 是否已被调用。

真正考虑一下您要在这里测试什么,例如假设您有一个 service 可以更改某些属性。

public class MyValue {
    public string Value { get; set; }
}

public class MyService {
    
    public void ChangeValues(MyValue value, string toValue) {
    
        value.Value = toValue;
    }
}

如果服务如下所示:

public class MyService {
    
    public void ChangeValues(MyValue value, string toValue) {
    
        value.Value = "toValue";
    }
}

当测试setter 是否被调用时,两种情况都会断言为真。

当您断言对value.Value 所做的更改时,只有第一种情况会成功。

【讨论】:

  • 我不确定我是否理解这部分“当您断言对 value.Value 所做的更改时,只有第一种情况会成功。”我明白我应该断言新值,而不是仅仅设置属性。我实际上是使用界面来做的,所以我更新了代码示例以反映这一点。问题是,如果我采用这种方法,我将为 POCO 创建接口,我想知道这样做是否正确,或者是否有替代方案来验证您建议的更改,我同意。
  • 在第一种情况下,使用作为参数 (toValue) 的属性值设置 value.Value 的第一个代码块。第二个代码块有错误代码,不会代表参数toValue的值。如果要验证对 POCO 所做的更改,请在调用方法之前创建对象的实例,并在调用方法后验证更改。 POCO 要求简单明了,我不建议为它们创建接口。只需实例化 POCO。
猜你喜欢
  • 2018-01-26
  • 1970-01-01
  • 2012-11-27
  • 2011-12-24
  • 1970-01-01
  • 2018-08-23
  • 2017-01-19
  • 1970-01-01
相关资源
最近更新 更多