Mocking .NET Without Hurting Its Feelings (DevSpace 2017)

JW
by John Wright0 views·Updated Jan 2, 2018
Powered by AI

Need to present on this topic?

Create your own polished presentation in minutes. Just describe what you need.

Free to try, no credit card required

Slide outline

  1. $ $ $
  2. DateTime.Now
  3. class DatabaseConnection
  4. class AnotherOne
  5. $$$
  6. File I/O
  7. FREE
  8. class DatabaseConnection
  9. class DependenciesHog

Transcript

Mocking .NET Without Hurting Its Feelings

DevSpace

Oct 13th, 2017

wrightfully.com/mocktalk

John M. Wright

john@wrightfully.com

@wright2tweet

www.wrightfully.com

© Copyright 2017 John M. Wright

class DependenciesHog

{

public string foo

{

get;

set;

}

private void bar(int x)

{

//I do stuff

}

public event BigEvent EventHorizon;

private void SpaceFiller()

{

while (true)

{

LookInteresting();

}

}

}

Why use a Mocking Framework?

Using Hand-Crafted, Artisanal Mocks

Brought to you in part by:

Need a dev job? Have a dev job to fill?

Stack Overflow's got you covered!

stackoverflowbusiness.com/talent

stackoverflow.com/jobs

mock

test double

What can they do?

mock.VerifyAllExpectations();

mock.AssertWasCalled(x => x.MyMethod());

mock

vs

stub

vs

stub

A rose by any other name

would smell as sweet

work about the same

mock types

How do they do it?

Per 5 Build Servers:

Code Examples (aka: What can you do?)

Code being tested

Example Test using a Mock

Using Moq Syntax

Unconstrained Code Examples

Typemock Syntax

Code being tested

MS Fakes Syntax

Unconstrained Frameworks:

Make Your Own Man-In-The-Middle Attack

Constrained Frameworks:

Limitations of Class Inheritance

Constrained Frameworks:

Class Inheritance On-Demand

internal types & members

Mocking Internal Types/Members

AssemblyInfo.cs

[assembly: InternalsVisibleTo("Your.TestAssembly")]

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]

sealed types

Generated Classes:

  • Inherit / Extend Mocked Type
  • Override virtual/abstract members
  • Check for configured stubs/mocks
  • Save details for later verification
  • Take action based on configuration

ICorProfilerInfo::

SetILFunctionBody

Hijacked Code:

  • Can change Behavior of ANY Type/Member
  • Doesn't rely on inheritance
  • Everything gets JIT'd, so anything can be mocked!
  • Injected code will:
  • Check for configured stubs/mocks
  • Save details for later verification
  • Take action based on configuration

The New Guy In Town

1

$ $ $

2

DateTime.Now

3

All that, plus:

  • public
  • internal
  • methods
  • properties
  • events
  • static
  • sealed
  • private
  • .NET libs
  • 3rd Party libs (Sharepoint)
4

What can

I expect?

5

private members

6

JITCompilationStarted

7

dynamic

8

Unconstrained

Constrained

9

public types & members

10

methods, properties, events

11
  • Open source
  • No extra software needed
  • Limited commercial support
  • May require design compromises
  • Proprietary (closed source)
  • Some require profiler application / VS plugin
  • Commercial support
12

class DatabaseConnection

{

}

13

substitute

14

More Info @

wrightfully.com/mocktalk

15

http://mimiandeunice.com/2011/07/19/expectations/

16

static types & members

17

shim

18

class AnotherOne

{

}

19

Using A Mocking Framework

20

Custom Mocks

21

$$$

UI

$$

Integration

$

Unit Tests

22

Mock

My test

value

23

File I/O

24

FREE

25

158 members!

26

partial

27

Unconstrained

28

.VerifyAll()

29

class DatabaseConnection

{

}

30

Great for testing "legacy" code.

Best fit for code written with testing in mind.

31

Class Being Tested

32

interfaces

33

fake

34

Tests

35

virtual / abstract members

36

strict

37

Constrained

38

class DependenciesHog

{

public string foo

{

get;

set;

}

private void bar(int x)

{

//I do stuff

}

public event BigEvent EventHorizon;

private void SpaceFiller()

{

while (true)

{

LookInteresting();

}

}

}