What does mockkConstructor do, and how do you stub and verify calls on instances created with `new` inside the code under test?
answer
- mockkConstructor intercepts new MyClass(...)
- Target with anyConstructed<T>()
- constructedWith<T>(EqMatcher(..)) filters by ctor args
- Real ctor body runs; stub per method
- Smell → prefer injecting the dependency
basics
~10 smockkConstructor(MyClass::class) makes every future MyClass(...) produce a mock. You then stub with every { anyConstructed<MyClass>().foo() } returns ... and verify with verify { anyConstructed<MyClass>().foo() }.
solid answer
~40 s`mockkConstructor(Foo::class)` intercepts the **constructor** so that any `Foo(...)` created afterwards — including instances the code under test news up internally, which you can't otherwise reach — becomes a mock. Because you don't hold the reference, you target it with the `anyConstructed<Foo>()` matcher: `every { anyConstructed<Foo>().bar() } returns 1` stubs every constructed instance, and `verify { anyConstructed<Foo>().bar() }` asserts. By default the real constructor body still runs (it's spy-like); pass `clear = true` or specify `localToThread`/recorded behaviour as needed. You can constrain by constructor args using a regular `mockk` constructor matcher with `constructedWith<Foo>(EqMatcher(...))`. Tear down with `unmockkConstructor(Foo::class)` or `unmockkAll()`. It's the heaviest of the three tools and a code smell — it usually means a collaborator should have been injected rather than instantiated inline.
code
kotlin · 12 linesclass Calculator { fun sum(a: Int, b: Int) = a + b }
class OrderService { fun total() = Calculator().sum(1, 2) }
@AfterEach fun tearDown() = unmockkAll()
@Test
fun mocksInternallyNewedCollaborator() {
mockkConstructor(Calculator::class)
every { anyConstructed<Calculator>().sum(any(), any()) } returns 99
assertEquals(99, OrderService().total())
verify { anyConstructed<Calculator>().sum(1, 2) }
}go deeper
May only recognise the name; not expected to use it fluently.
Can stub/verify with anyConstructed<T>() and knows it needs teardown.
Knows constructedWith filtering, spy-like body execution, and its limitations.
Treats it as a design smell and steers teams toward DI/factories so constructor mocking is unnecessary.
## The problem: un-injectable `new` Sometimes the code under test creates a collaborator itself: ```kotlin class OrderService { fun total(): Int = Calculator().sum(1, 2) // newed internally — no seam to inject } ``` You cannot pass a mock `Calculator` in. `mockkConstructor(Calculator::class)` installs an interceptor on the constructor so that **every instance created from then on** is a MockK proxy. ## Targeting instances you never see: anyConstructed Since the test never holds the constructed object, you reference it through the special matcher **`anyConstructed<T>()`**, which represents "any instance produced via the mocked constructor": ```kotlin mockkConstructor(Calculator::class) every { anyConstructed<Calculator>().sum(any(), any()) } returns 99 assertEquals(99, OrderService().total()) verify { anyConstructed<Calculator>().sum(1, 2) } ``` ## Constraining by constructor arguments If you only want to affect instances built with specific args, use `constructedWith`: ```kotlin mockkConstructor(Calculator::class) every { constructedWith<Calculator>(EqMatcher(2)).scale() } returns 4 ``` This matches only `Calculator(2)` instances. ## Spy-like by default Like `mockkObject`, the **real constructor body runs** unless you stub the methods you care about; only stubbed methods are faked. There is no `relaxed` blank-instance creation — you opt into behaviour per method. ## Teardown Constructor interception is global JVM state. Reset with `unmockkConstructor(Calculator::class)` or `unmockkAll()` in `@AfterEach`. The `mockkConstructor(Foo::class) { }` lambda form auto-unmocks. ## Limitations and smell - It cannot intercept constructors of `final`/inline value classes the same way and has caveats with classes the JVM has already heavily inlined. - It is the most invasive of the three (`mockkObject`/`mockkStatic`/`mockkConstructor`). - Reaching for it is usually a sign the design hides a dependency. The cleaner fix is **dependency injection** — pass a `Calculator` (or a factory `() -> Calculator`) into `OrderService` so a plain `mockk<Calculator>()` suffices, no bytecode constructor patching needed.
- How do you reference an object you never get a handle to because the code newed it internally?Use the anyConstructed<T>() matcher inside every {} / verify {}; it represents any instance produced through the mocked constructor.
- When would you refactor instead of using mockkConstructor?Almost always: if you control the class, inject the collaborator (or a factory) so a plain mockk<T>() works. Reserve mockkConstructor for third-party classes you can't change.
It's like rigging the factory so every car coming off the line is secretly a remote-controlled dummy, even ones you never ordered.
saying these in an interview costs you the question
- Trying to capture the constructed instance into a variable instead of using anyConstructed<T>()
- Believing the constructor body is skipped (it runs unless methods are stubbed)
- Treating mockkConstructor as a first choice rather than a last resort
- Forgetting unmockkConstructor/unmockkAll teardown