Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add a way to mock a constructor with defined values #209

Closed
3 tasks done
Tryle opened this issue Dec 29, 2018 · 40 comments · Fixed by sip3io/sip3-parent#128
Closed
3 tasks done

Feature: Add a way to mock a constructor with defined values #209

Tryle opened this issue Dec 29, 2018 · 40 comments · Fixed by sip3io/sip3-parent#128

Comments

@Tryle
Copy link

Tryle commented Dec 29, 2018

Prerequisites

Please answer the following questions for yourself before submitting an issue.

  • I am running the latest version
  • I checked the documentation and found no answer
  • I checked to make sure that this issue has not already been filed

Expected Behavior

Actually we can mock constructors but there is no way to handle constructors parameters. Something like:

class MockCls(val minValue: Int) {
  fun add(a: Int, b: Int) = minValue + a + b
}

mockkConstructor(MockCls::class)

every { anyConstructed<MockCls>(10).add(1, 2) } returns 14

assertEquals(14, MockCls(10).add(1, 2)) // note new object is created

verify { anyConstructed<MockCls>(10).add(1, 2) } // success
verify { anyConstructed<MockCls>(5).add(1, 2) } // fail

For reference there is a question on SO about that.

@oleksiyp oleksiyp added this to To do in MockK features Dec 29, 2018
@mpost
Copy link

mpost commented Jan 8, 2019

I am facing the same requirement to retrieve the constructor arguments for the created class. It is good to see a feature request which is not closed immediately so it seems to be at least feasible. Hope to see it soon.

@pascalpfeil
Copy link

I need this, too.

@erikhuizinga
Copy link
Contributor

erikhuizinga commented Mar 7, 2019

I'm not sure, but if I read the readme correctly, the current implementation of mockkConstructor can only create one mock for all constructed instances, am I right? By that one mock, I mean the object you get through the anyConstructed function.

This, of course, is not ideal for true power to the user. Ideally we could do something like this:

// Note this class has two constructors
class Cls() {
    constructor(a: Any?) : this()
}

@Test 
fun `some test`() = mockkConstructors(Cls::class) {
    val mock1 = mockk<Cls>()
    val mock2 = mockk<Cls>()
    val a = 0

    every { Cls() } returns mock1
    every { Cls(a) } returns mock2
}

Notes:

  • Note the 's' in mockkConstructors: this would mock all available constructors, which can potentially be many.
    • OTOH, as a MockK user I'd want the ability to specifically mock a constructor with a specific signature.
  • Note that I return different instances in different cases (in this case mockks, but of course, these can be any valid instance).

@oleksiyp
Copy link
Collaborator

oleksiyp commented Mar 7, 2019

Yes, you are right. The underlying mocking stub is only one. And all the calls from created objects via mockkConstructor are delegated to this stub.

Returning arbitrary object/mocks as a result of the constructor calls is not possible. But attaching different stubs is possible.

I've made an attempt to implement a variety of constructors in a simple way: #267
But seems full rewrit\e is needed. This implementation lacks a few things.

I have an idea that constructor call should be somehow indistinguishable from method call at the level of DSL engine. This will unify it the way you can apply all the machinery with matchers.

@stale
Copy link

stale bot commented Jul 23, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale just put an important tag.

@stale stale bot added the stale label Jul 23, 2019
@erikhuizinga
Copy link
Contributor

@Stale[bot] come on man bot! No activity means no activity, but not that an issue should be closed! This way active issues or even bugs might lose visibility.

@stale stale bot removed the stale label Jul 23, 2019
@stale
Copy link

stale bot commented Sep 21, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. If you are sure that this issue is important and should not be marked as stale just ask to put an important label.

@stale stale bot added the stale label Sep 21, 2019
@stale stale bot closed this as completed Sep 28, 2019
@darrengyl
Copy link

We need this! It will be really useful to test constructors with parameters

@bboyairwreck
Copy link

can i asked why this was closed? This would be really nice functionality that has a real use cases. Stop closing this ticket bot

@oleksiyp
Copy link
Collaborator

Check #356

@oleksiyp oleksiyp reopened this Oct 19, 2019
@stale stale bot removed the stale label Oct 19, 2019
@espertus
Copy link

I would like this too.

@Richrocksmy
Copy link

In relation to this, when mocking constructors that are not the default constructor ie they have parameters the mocking doesn't appear to work and instead the real code gets called.

I think that adding the ability to mock constructors individually would fix this issue.

@marklapasa
Copy link

bump - would like to see this too

@rkokhatskyi
Copy link

+1 for this feature

@thesultanster
Copy link

+1 for this as well

@davidcre
Copy link

davidcre commented Jun 24, 2020

+1 the current implementation of constructor mocking is not enough.
Thank you for considering this feature 👍

@noah-iam
Copy link

I am facing the same issue while mocking the class with parameter constructor.

io.mockk.MockKException: No matching constructors found:

@miva2
Copy link

miva2 commented Jul 6, 2020

I tried to write this but apparently it's not possible
every { SomeClass(param1, param2) } returns SomeClassMock

I haven't used MockK a lot yet but expected it to work like that.

@trietbui85
Copy link

+1 for this feature.

@distante
Copy link

distante commented Sep 4, 2020

I am also very interested in this.

@othiagosouto
Copy link

+1

@JureSencar
Copy link

+1

The workaround I use (in case I own the code) is to define a factory method with @VisibleForTesting to the companion object of the class and mockk that. Of course, changing source for the sake of testing is not nice and it is not an option if you don't own the code. Thus, I am definitively interested in this feature.

@kenaiX
Copy link

kenaiX commented Nov 16, 2020

+1

10 similar comments
@martinezdputraa
Copy link

+1

@JanCizmar
Copy link

+1

@om32
Copy link

om32 commented Jan 9, 2021

+1

@Jethril
Copy link

Jethril commented Jan 14, 2021

+1

@campino-rocks
Copy link

+1

@chmod
Copy link

chmod commented Jan 22, 2021

+1

@Diones
Copy link

Diones commented Jan 26, 2021

+1

@gregorgrisza
Copy link

+1

@konstantin-tkachuk
Copy link

+1

@felipezad
Copy link

+1

@FGuyet
Copy link

FGuyet commented Feb 9, 2021

+1!

1 similar comment
@olgachrostowska-meelogic

+1!

@AshokKumarMandava
Copy link

AshokKumarMandava commented Mar 1, 2021

+1

2 similar comments
@KevinBassaDevelopment
Copy link

+1

@Bebooo43
Copy link

Bebooo43 commented Mar 8, 2021

+1

@erikhuizinga
Copy link
Contributor

Has this partially/entirely been fixed in v1.11.0?

@Raibaz
Copy link
Collaborator

Raibaz commented Mar 17, 2021

Yep, v1.11.0, just released, adds constructedWith that fixes this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
MockK features
  
To do
Development

Successfully merging a pull request may close this issue.