How do I set a default to call a method on an instance with minitest?

I am learning ruby ​​and TDD. I am using Minitest as a unit test framework. I currently have a class (pair) that will be initialized with two instances of the second class (member). To unit test it, I would like to create two mock members and pass them to the initialize method:

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

      

It works, but it is not 100% correct. If I change the equality string equal to

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

      

To compare the value of the stored member with the value of the layout (which I would like to store) I get

MockExpectationError: no more waiting for: name: []

I honestly don't get it. It looks like the "wait" I set earlier was already "used" during my code execution.

This is not exactly what I'm looking for. I don't want to check how many times a method is called, I would like to define a default value that will be returned when the method is called on a given instance.

How can I do this with minitest?

I did some searches and I read about stubs in Minitest. But as far as I understood, they are meant to stub out the method call for each instance of the class.

I would like to create two participants and define their name and division information without using a real class, so I can focus my test on the object under test.

ps: this is init in my pair's class

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

      

and participant class

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

      

+3


source to share


1 answer


You are close to the rule.

Minitest provides mocks and stubs:

  • Use mock when you want to check which calls will be called and how many times.

  • Use a stub when you want a placeholder object, such as an object with a method, that always returns the same value.

First you try to test if your Pair.new is setting the objects correctly.

You don't need a layout and you don't need a stub; you can use plain old Ruby object.

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

      



Suppose you decide to add complex initialization code for a pair, and then you want to verify that the initialization code does not accidentally change the names and descriptions of the participants.

You don't need mockery, and you don't need stubs; you can use plain old Ruby objects.

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)

      

All of the above are plain old Ruby objects, not mocks and stub.

The reason you switch from plain old Ruby objects to mocks or stub is if you want to explicitly check which methods are being called (so use mock), or if the setup is more complicated or time consuming (so use a stub).

+3


source







All Articles