【问题标题】:Assert that method was called in a unit test断言在单元测试中调用了该方法
【发布时间】:2014-05-15 04:41:22
【问题描述】:

我想断言调用了对我的真实对象(被测系统)的调用。这是我的测试

// Arrange
var contextFactory = A.Fake<IContextFactory>();
var db = A.Fake<IDatabase>();
A.CallTo(() => contextFactory.GetContext()).Returns(db);
var vm = new MainViewModel(contextFactory);

// Act
vm.Loaded();

// Assert
A.CallTo(() => vm.LoadModels(db)).MustHaveHappened();

我收到一个 ArgumentException,上面写着“指定的对象未被识别为假对象。”如何测试 MainViewModel 中的 LoadModels() 方法是否被 Loaded() 方法调用?

编辑

我这样做的原因是因为 Loaded() 方法在应用程序启动时调用了一堆其他方法,我不想为每个测试设置所有其他东西,我只想确保调用所有正确的方法,然后单独测试它们。我乐于接受有关解决此问题的更好方法的建议。

这里是 Loaded 和 LoadModels 方法

internal virtual void Loaded()
{
    using (var db = _contextFactory.GetContext())
    {
        LoadModels(db);
        // bunch of other method calls
    }
}

internal virtual void LoadModels(IDatabase db)
{
    Models = new ObservableCollection<Model>(db.Models);
}

【问题讨论】:

  • 你没有断言被测系统被调用。您断言被测系统调用了某些其他预期函数。
  • 这不能回答我的问题“如何测试 MainViewModel 中的 LoadModels() 方法是否从 Loaded() 方法中调用?”
  • 它不应该回答你的问题。它应该指出你做错了事。通常调用 LoadModels 的事实并不重要。重要的是,给定某些参数和模拟数据(排列),并且在调用 Loaded 方法之后(动作),从方法返回的值或存储在公共属性中的值是预期的值(断言)。
  • 我在这里发现了另一个非常相似的问题stackoverflow.com/questions/17929758/…
  • @reggaeguitar 我建议您测试contextFactory.GetContext()db.Models 都被调用,因为这是预期的功能,而不是对象的内部工作。换句话说,测试类似于Loaded loads the models from the database

标签: c# fakeiteasy


【解决方案1】:

您正在验证的方法 (vm.LoadModels) 不属于伪造 (db)。您只能验证假的方法,而不是碰巧将假作为参数的方法。

【讨论】:

  • 那么我将如何测试从 MainViewModel 类中的 Loaded 方法调用 LoadModels 方法呢?是否需要将 LoadModels 方法放入新类中?
  • 不,你只需要把vm也弄成假的。做vm = A.Fake&lt;MainViewModel&gt;(),你甚至不需要其他的假货。只要不密封就可以。你可能会遇到方法没有被调用的问题,因为它们会自动重载,但我对你的类了解不够,无法进行调用。如果它不起作用,请发表评论,我会协助解决。
  • 我试过了,当我进入 vm.Loaded() 调用时,它只是跳转到下一行并且断言失败。 Loaded() 方法在应用程序启动时调用了一堆其他方法,我不想为每个测试设置所有其他东西,我只想确保调用所有正确的方法然后测试它们个人。
  • @reggaeguitar 看看下面的扩展方法:gist.github.com/Alxandr/4ab0475c0e1ec86dbad8。在处理 FakeItEasy 时,我经常使用它,甚至创建了一个问题,即这在框架中应该更容易,但那是无关紧要的。它将自动设置为调用基本方法。虽然,正如其他 cmets 指出的那样,您可能正在测试错误的东西,而不是测试 vm.LoadModels 是否被调用,您可能应该测试 contextFactory.GetContext() 是否因此而被调用。
  • LoadModels 是虚拟的吗?
【解决方案2】:

我最终将LoadModels() 的功能移动到另一个实现IStartupDataLoader 的类,然后我就可以像这样测试它了

// Arrange    
var sdl = A.Fake<IStartupDataLoader>();
var exp = A.Fake<ObservableCollection<Model>>();
A.CallTo(() => sdl.LoadModels()).Returns(exp);
var sut = new MainViewModel(sdl);

// Act
sut.Loaded();

// Assert
Assert.That(exp == sut.Models);

【讨论】:

    猜你喜欢
    • 2011-04-19
    • 1970-01-01
    • 2013-08-03
    • 2013-03-18
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    相关资源
    最近更新 更多