Summer Sale! All accounts are 50% off this week.

netdjw's avatar
Level 15

How to mock/spy/fake a non existing class in unit tests?

I have a task to create a webshop basket for example. Call it Basket class. This Basket has many relations for shipping address, billing address, products, consts, discounts, etc.

When I create this Basket class the other related classes doesn't exists yet.

How can I unit test the Basket class without related classes, if I want to test relations too?

0 likes
18 replies
tykus's avatar

Is it really a unit test if you’re also testing the relations; just build of the world that you need to test and then test it?

netdjw's avatar
Level 15

@tykus I don't want to test all aspects of a relations. My expectations only this:

  • the function must be exists
  • the function mist be return a Collection instance
  • the collection must contains an expected class (for example a Discount model)
tykus's avatar

@netdjw this all feels very spell-checking. Personally, I would drive this out in feature tests - very quickly if the relationship is not present and correct, the tests will fail. If you must...

$model = new Model; // your class under test
$relation = $model->related();  // use relationship function
$related = $relation->getRelated();

$this->assertInstanceOf(HasMany::class, $relation);
$this->assertInstanceOf(Other::class, $related);

A HasMany always returns a Colleection, so we're not testing that

netdjw's avatar
Level 15

@tykus It looks good, but this test will fail if the Other class does not existing. How to prevent this issue?

tykus's avatar

@netdjw of course it should fail - what are you asserting otherwise!

netdjw's avatar
Level 15

@tykus the question is: how do I lie to the system: this class is exists only for this test.

netdjw's avatar
Level 15

@tykus If it's not possible or doen't make sense, both can be a good answer to me

netdjw's avatar
Level 15

@tykus My goal is I want to make my test independent of existing of other, related classes

tykus's avatar

@netdjw you're asking the test to make an assertion that a relationship should return a Collection of fictional/not-yet-implemented classes; is this correct?

tykus's avatar
tykus
Best Answer
Level 104

@netdjw I would test only what the system is or should do, not anticipating code I will write in the future. Whenever you implement Other and define the relationship, then add those Test Examples.

netdjw's avatar
Level 15

@tykus So you say, if I have a related class I can test the original class only if reated class is existing too.

The future-implemented relation should be test only if both classes exists.

Right?

tykus's avatar

@netdjw yeah, otherwise what value does the test have if it is testing for non-existing classes. Testing is about confidence... not confidence tricks

tykus's avatar

@netdjw no problem - mark the thread closed if your question has been answered

netdjw's avatar
Level 15

@tykus I don't see any option for close thread. Where is it?

Please or to participate in this conversation.