【问题标题】:How to set a default value for a method call in a instance with minitest?如何为 minitest 实例中的方法调用设置默认值?
【发布时间】:2015-06-07 18:16:12
【问题描述】:

我正在学习 ruby​​ 和 TDD。我使用 Minitest 作为我的单元测试框架。 目前我有一个类(对),它将用第二个类(参与者)的两个实例进行初始化。为了对其进行单元测试,我想创建两个参与者模拟并将它们传递给初始化方法:

def test_init
    participantOne = Minitest::Mock.new
    participantOne.expect(:name, "P1")
    participantOne.expect(:dept, "D1")

    participantTwo = Minitest::Mock.new
    participantTwo.expect(:name, "P2")
    participantTwo.expect(:dept, "D2")

    pair = Pair.new(participantOne, participantTwo)

    assert_equal("P1", pair.participantOne.name) #I would like to change this line
    assert_equal("P2", pair.participantTwo.name) # and this line


end

这可行,但不是 100% 正确。 如果我将断言相等行更改为

assert_equal(participantOne.name, pair.participantOne.name) #I would like to change this line

为了将存储的参与者的值与模拟的值(我想存储)进行比较,我得到了

MockExpectationError: 没有更多期望可用于 :name: []

说实话,我不是很明白。在我的代码执行过程中,我之前设置的“期望”似乎已经被“使用”了。

这不是我想要的。我不想验证一个方法被调用了多少次,我想定义一个在给定实例中调用该方法时返回的默认值。

如何使用 minitest 做到这一点?

我进行了一些搜索,并在 Minitest 中阅读了有关存根的信息。但据我了解,它们旨在为类的每个实例存根方法调用。

我想创建两个参与者并定义他们的姓名和部门信息,而不使用真实的班级,这样我就可以将我的测试重点放在被测主题上。

ps: 这是我的pair类中的init

def initialize(participantOne, participantTwo)
    @participantOne = participantOne
    @participantTwo = participantTwo
end

和参与者班级

def initialize(name, dept)
    @name=name
    @dept=dept
end

【问题讨论】:

    标签: ruby unit-testing minitest


    【解决方案1】:

    你几乎是正确的。

    Minitest 提供模拟和存根:

    • 当您想要验证将调用哪些方法调用以及调用次数时,请使用模拟。

    • 当您需要占位符时使用存根,例如具有始终返回相同值的方法的对象。

    您首先要测试的是您的 Pair.new 是否正确设置了对象。

    您不需要模拟,也不需要存根;您可以使用普通的旧 Ruby 对象。

    p1 = Object.new
    p2 = Object.new
    pair = Pair.new(p1, p2)
    assert_equal(p1, pair.participant1)
    assert_equal(p2, pair.participant2)
    

    假设您决定添加一些复杂的 Pair 初始化代码,然后您想测试初始化​​代码是否不会意外更改参与者的姓名和描述。

    您不需要模拟,也不需要存根;您可以使用普通的旧 Ruby 对象。

    p1name = "p1n"
    p1desc = "p1d"
    p1 = Participant.new(p1name, p1desc)
    
    p2name = "p2n"
    p2desc = "p2d"
    p2 = Participant.new(p2name, p2desc)
    
    pair = Pair.new(p1, p2)
    
    assert_equal(p1name, pair.participantOne.name)
    assert_equal(p1desc, pair.participantOne.desc)
    assert_equal(p2name, pair.participantTwo.name)
    assert_equal(p2desc, pair.participantTwo.desc)
    

    以上所有内容都是普通的旧 Ruby 对象,而不是模拟或存根。

    您将从普通的旧 Ruby 对象切换到 mock 或 stub 的原因是,如果您想显式测试调用了哪些方法(所以使用 mock)或者设置更复杂或耗时(所以使用 stub) .

    【讨论】:

    • 太好了,谢谢!我不习惯 ruby​​ 的“思维方式”,所以我永远不会注意到我可以将 Participant 更改为 Object。关于第二种方法(您创建真正的参与者),我只有一个问题:参与者类的更改可能会导致此测试中断,我想避免这种情况。有什么办法可以做到吗?
    • 您问“参与者班级的变化可能会导致此测试中断,我想避免这种情况。有什么办法可以做到吗?”是的,当然这取决于您要更改的内容。随着您的需求不断发展,您的测试也随之发展。您可以使用单元测试(例如这些),也可以使用功能测试和集成测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    相关资源
    最近更新 更多