Skip to content

pchudzik/springmock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

81 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

springmock

Build Status Coverage Status

Introduction

Alternative spring mocking infrastructure. With pluggable mocking library support. The purpose is to allow you to easily inject mocks created by any mocking library into your spring tests. Currently, mockito and spock mocks are supported.

Why? Spring boot supports only mockito as mocks provider which is great if you write tests in java. When using spock you might want to use mocks created by spock because of syntactic sugar they offer. It is similar to @MockBean any @SpyBean from spring-boot-test, but allows you to use mocks created by a library of your choice.

Contents

Features

Requirements

Basic requirements to make it running:

  • java8
  • spring <= 4.3.6
  • springboot <= 1.4.4

Required spring modules: spring-context & spring-test

Mockito

mockito-core <= 1.10.x is required and must be provided. Samples with spring-boot

Spock

To get spock mocks running you'll need:

  • spock-core 1.1-groovy-2.4
  • spock-spring 1.1-groovy-2.4

Samples with spring-boot

Installation

Releases

With Mockito as mocks provider

mvn

Maven Central

<dependency>
  <groupId>com.pchudzik.springmock</groupId>
  <artifactId>springmock-mockito</artifactId>
  <version>1.2.0</version>
</dependency>
gradle
testCompile('com.pchudzik.springmock:springmock-mockito:1.2.0')

With Spock as mock provider

mvn

Maven Central

<dependency>
  <groupId>com.pchudzik.springmock</groupId>
  <artifactId>springmock-spock</artifactId>
  <version>1.2.0</version>
</dependency>
gradle
testCompile('com.pchudzik.springmock:springmock-spock:1.2.0')

sample pom.xml with spring-boot

sample build.gradle

Snapshots

Repository configuration

Add sonatype snapshots repository to repositories list

Maven:

<repositories>
  <repository>
    <id>sonatype-snapshots</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots</url>
  </repository>
</repositories>

Gradle:

repositories {
  maven {
    url 'https://oss.sonatype.org/content/repositories/snapshots'
  }
  mavenCentral()
}

Mockito as mocks provider

Include mvn dependency:

<dependency>
  <groupId>com.pchudzik.springmock</groupId>
  <artifactId>springmock-mockito</artifactId>
  <version>1.2.1-SNAPSHOT</version>
</dependency>

Or gradle dependency:

testCompile('com.pchudzik.springmock:springmock-mockito:1.2.1-SNAPSHOT')

Spock as mocks provider

Include mvn dependency:

<dependency>
  <groupId>com.pchudzik.springmock</groupId>
  <artifactId>springmock-spock</artifactId>
  <version>1.2.1-SNAPSHOT</version>
</dependency>

Or gradle dependency:

testCompile('com.pchudzik.springmock:springmock-spock:1.2.1-SNAPSHOT')

Usage

Mock injection infrastructure is the same and is independent to selected mock provider.

Once mock is injected you can use it accordingly to selected mocking library for mockito and for spock

Mocks

To inject mocks just annotate field you want to be initialized and injected with mock using @AutowiredMock and you are good to go

@AutowiredMock AnyService anyService;

@Test
public void should_inject_mock() {
  assertTrue(mockingDetails(anyService).isMock());
}

or in spock:

@AutowiredMock AService service

def "should inject mock"() {
  given: service.hello() >> "mock"
  when:  final result = service.hello()
  then:  result == "mock"
}

You can specify name of the registered mock using name param. Which will result in registering mock with the specific name in the spring context (like in with @Bean#name). If name is not provided bean name will be the same ase the field name on which it is declared.

You can also provide list of aliases for mock using alias attribute.

Sample test case with mockito mocks

Sample test case with spock mocks

Spies

Right now springmock can not create spies on the fly and inject them in the context. In order to spy on the bean it must already be registered in the context. It needs appropriate object to already exist in spring context.

@AutowiredSpy Service service;

@Test
public void should_inject_spy() {
  assertTrue(mockingDetails(service).isSpy());
}

or in spock:

@AutowiredSpy Service service

def "should inject spy"() {
  when: service.hello()
  then: 1 * service.hello() >> "spy!"
}

You can specify name of the bean which should be replaced by created spy using name attribute. if no name is defined then destination bean will be matched field name or by class.

Configuration

Mockito

Annotate @AutowiredMock or @AutowiredSpy field with @MockitoDouble. Examples:

Spock

Annotate @AutowiredMock or @AutowiredSpy field with @SpockDouble. Examples:

Problems

Please report any problems with the library using Github issues. I'd really appreciate failing test case included in issue description or as PR.

Development

Versions

Setting version is done using script.mvnw/update-versions.groovy. From this script versions are loaded from version.properties and applied on all required projects (root + samples).

To apply versions from property file execute:

./mvnw -P versions-update gplus:execute -N

Deployment

Private key must be imported into pgp.

In order to do the release, release versions must be set in poms and one must execute goal:

SONATYPE_USERNAME=secret_user \
SONATYPE_PASSWORD=secret_password  \
./mvnw --settings .mvn/settings.xml -P release clean deploy

Changelog

1.2.0 springmock-spock - 2018.12.03

  • register field name as double alias - #9
  • added support for springboot2.1 - #17

1.2.0 springmock-mockito - 2018.12.03

  • register field name as double alias - #9
  • added support for springboot2.1 - #17

1.1.2 springmock-spock - 2017.09.17

  • Fixed spy reset code to handle missing beans - #15
  • Single bean instance will be replaced by mock/spy without matching name #10

1.1.2 springmock-mockito - 2017.09.17

  • Single bean instance will be replaced by mock/spy without matching name #10

1.1.0 springmock-mockito - 2017.09.06

  • mocks configuration - @MockitoDouble
  • fixed mocks reset in context hierarchy
  • optimizations to listener responsible for mock reset between tests methods executions
  • class level mocks sample
  • mocks and spies can be created and injected into @Configuration classes (mock injection example, spy injection example)
  • added possibility to create spies without real object present in context. Word of warning. It will produce partial mock, which might not work as you'd expect it to work and might cause some unexpected failures. In general yous should spy on existing bean instance, unless it is very trivial bean without any fields.

1.1.0 springmock-spock - 2017.09.06

  • mocks configuration - @SpockDouble
  • optimizations to listener attaching mocks to the currently running specification
  • should not fail when executing on mixed code base with spock and junit tests - #11
  • class level mocks sample
  • mocks and spies can be created and injected into @Configuration classes (mock injection example, spy injection example)
  • added possibility to create spies without real object present in context. Word of warning as in mockito it might produce not properly initialized object. In spock you have higher level of control over mocks creation and you can initialize object properly using SpockDouble.constructorArguments see integration test case.

1.0.0 - 2017.07.22

  • @AutowiredMock with name and aliases support
  • @AutowiredSpy with name and aliases support