Possible to Freeze a Mock of a func? - unit-testing

I want to test that my Func type is actually executed. To do that I have created a Mock, but I run into an Exception from Autofixture. I tried to Freeze just the Func (without the Mock) and this works. Can someone explain what's happening or guide me to the right way of doing this?
Exception message:
An exception of type 'Ploeh.AutoFixture.Kernel.IllegalRequestException' occurred in Ploeh.AutoFixture.dll but was not handled in user code
Additional information: A request for an IntPtr was detected. This is an unsafe resource that will crash the process if used, so the request is denied. A common source of IntPtr requests are requests for delegates such as Func or Action. If this is the case, the expected workaround is to Customize (Register or Inject) the offending type by specifying a proper creational strategy.
Code:
public class DomainClassDummy
{
public int Id { get; set; }
}
var frozenFunc = F.Freeze<Func<int, DomainClassDummy>>(); //works
var frozenMockOfFunc = F.Freeze<Mock<Func<int,DomainClassDummy>>>(); //fails

This behavior is due to AutoConfiguredMoqCustomization.
When AutoFixture is customized with AutoConfiguredMoqCustomization, it relays the creation of the Mock instances to a special builder.
This builder, however, gets the inner type Func<int,DomainClassDummy> and creates a mock out of it, passing the two arguments of its constructor: objectand IntPtr and here is where the problem lies.
The default builder for delegates, creates its instances out of a Linq Lambda Expression.
To make it work, you'll have to create the mock yourself and inject it to AutoFixture. Injecting it is the same as freezing, except you specify the instance yourself, instead of telling AutoFixture to create one for you.
Here is what you should do:
var mockOfFunc = new Mock<Func<int, DomainClassDummy>>();
F.Inject(mockOfFunc);

The explanation given by Marcio Rinaldi is technically correct, but I found the solution unsatisfactory, so I added this ability to AutoFixture.AutoMoq 3.31.1.
This test now passes:
[Fact]
public void FixtureCanFreezeUsableMockOfFunc()
{
// Fixture setup
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var expected = fixture.Create<Uri>();
var mockOfFunc = fixture.Freeze<Mock<Func<Guid, decimal, Uri>>>();
mockOfFunc
.Setup(f => f(It.IsAny<Guid>(), 1337m))
.Returns(expected);
// Exercise system
var actual = mockOfFunc.Object(Guid.NewGuid(), 1337m);
// Verify outcome
Assert.Equal(expected, actual);
// Teardown
}

Related

How to use #MockBean without having to #Inject the Bean again?

Is there a more concise / elegant way to reach this functionality in Micronaut?
#MicronautTest
class ControllerTest {
#Inject
#field:Client("/")
lateinit var client: RxHttpClient
#Inject
lateinit var redeemService: RedeemService
#MockBean(RedeemService::class)
fun redeemService(): RedeemService = mockk {
every { validate(any()) } returns true
}
#Test
fun test() {
// some logic triggering a call to redeemService
verify(exactly = 1) {
redeemService.validate("123")
}
}
}
To me it looks like redundant work to have to declare the #MockBean and then also having to #Inject the previously declared #MockBean.
From what I remember, in Spring Boot this is just an annotation on a lateinit var.
Did I misunderstand or overlook something?
You need the mock bean, for replacing the service and inject it everywhere in your application .. if you want to do some verification you eighter have to inject it back or create instance within your class and return that with the mock bean
private val redeemService: RedeemService = mockk {
every { validate(any()) } returns true
}
#MockBean(RedeemService::class)
fun redeemService() = redeemService
Usually, MockBean are NO-OP collaborators that are intended to be DI-ed into dependent beans instead of relying on concrete bean implementations.
If within a test fixture ~ your tested feature scope ~ you have to verify collaborator calls or provide custom response to other collaborators calls, then you have to inject it.
This may seem, as stated, like redundancy but it's not and it SHOULD be done in such a way otherwise Micronaut (or any other framework doing so) would have a little design flaw.
Relying on custom implementations (annotations in this case) to act as bean providers and injection points within tests would result in non-deterministic behavior and internal tight-coupling to framework specificities as you will be injecting your dependencies in your test fixture differently from the way you'll be doing it in your actual application code, and that should be avoided.
In short, if your bean (mock or concrete) make it to the your test implementation through the #Inject annotation, then you are assured it will work the same when injected into real application code since a test fixture is a bean itself.

Why we use interface for mocking methods Golang

I am new to Golang and have been exploring but not clear about mocking in unit tests. Can anyone explain following specific questions ?
Question1: For writing unit tests in Golang, why we need to have interfaces to mock methods, why not only struct ?
Question2: Why we inject the interface in struct(where we call external method)
With struct -
type GlobalData struct {}
var (
GlobalObj = GlobalData{}
)
func (g GlobalData) GetGlobalData(a string) string{
return a
}
With interface definition-
type GlobalInterface interface {
GetGlobalData(a string) string
}
type GlobalData struct {}
var (
GlobalObj = GlobalData{}
)
func (g GlobalData) GetGlobalData(a string) string{
return a
}
Thanks
Question 1: For writing unit tests in Golang, why we need to have interfaces to mock methods, why not only struct ?
Answer: Its not mandatory
Question 2: Why we inject the interface in struct(where we call external method)
Answer: Because, it helps you to replace the actual function call (that might trigger some out of scope actions as a part of unit test , such as database call, some API call etc) by injecting a MockStruct (which will be implementing the same interface that is there in the actual code). Polymorphism in simple words.
So, you create a MockStruct and define your own mockMethods to it. As polymorphism, your unit test pick MockStruct without complaining. Calling actual DB or http endpoints do not come under unit testing.
Just for reference, I can point you to one of my github codebase where I wrote a small test case for a file. As you can see I mocked :
GuestCartHandler interface , that allowed me to not call the actual implementation
Mocked sql connection using "github.com/DATA-DOG/go-sqlmock" package. This helped me to avoid establishing actual db client (so, no dependency of database while unit testing)
Let me know if you get the idea conceptually or do you need some more clarification.
If you have methods on types in package user let's say, ex.
package user
type User struct {
name string
}
func (u *User) GetUserProfile() UserProfile{}
And now on import in catalog package :
package catalog
import user
func getUserCatalog(user user.User) []catalog {
user.GetUserProfile()
}
Now to test getUserCatalog method there are 2 ways:
1. var getUserProfileFunc = user.GetUserProfile
using this approach mock can be easily passed at test run time like:
getUserProfile = func() UserProfile {
return fakeUserProfile
}
this is the easiest way to test it.
Now there is another way using interface, in package user add an interface like
type UserInterface interface {
GetUserProfile() UserProfile
}
if User package is a library on which you don't have control then create your own interface, type and use this.
In this case testing in catalog package will become like:
because now methods will be invoked from UserInterface type not from UserType, hence while testing :
UserInterface = fakeUserStruct
and follow below steps
//1. define type of func to return
type typeGetUserProfile func() UserProfile
//2. create a var to return
var mockedGetUserProfile typeGetUserProfile
//3. create a type
type FakeUser struct{}
//4. implement method interface
func (user *FakeUserStruct) GetUserProfile() UserProfile{
return mockedGetUserProfile
}
now when running test :
mockerGetUserProfile = func() UserProfile {
return fakeUserProfile
}
There is mock library which helps in creating boilerplate code for mocking. Check this https://github.com/stretchr/testify
There are many other mock library, but I had used this one, this was really cool.
I hope this helps.
if not please let me know, i'll give some example code and push it to Github.
Also please check https://levelup.gitconnected.com/utilizing-the-power-of-interfaces-when-mocking-and-testing-external-apis-in-golang-1178b0db5a32

Unit Testing Lambda Expressions

I have a method that is shown as below and this in turn call multiple private methods, that I won't be posting here.
#Bean
public CommandLineRunner registerStartersAndReaders(final Vertx vertx, final SpringVerticleFactory springVerticleFactory,
final SpringUtil springUtil, final GslConfig gslConfig) {
return args -> {
// Scan all the beans annotated with the #ElasticsearchBatchDataListener annotation.
List<Pair<Object, Method>> listenerMethods = springUtil.getListenerMethods();
// Deploy the starters per listener.
deployVerticle(listenerMethods, jsonConfig -> deployStarterVerticle(vertx, springVerticleFactory, jsonConfig), config);
// Deploy the reader verticles.
deployVerticle(listenerMethods, jsonConfig -> deployReaderVerticle(vertx, springVerticleFactory, jsonConfig), config);
setupTriggers(vertx, listenerMethods, config);
};
}
Then I have a test method for it :
#Test
public void registerStartersAndReadersTest() {
when(springUtil.getListenerMethods()).thenReturn(value);
CommandLineRunner runner = config.registerStartersAndReaders(vertx, springVerticleFactory, springUtil, config);
assertNotNull(runner);
}
Here, all the parameters passed into the method call are mocks. The problem is, when I run this test, it passes but it returns the value without getting into the private methods as it just returns 'args'.
Can someone please guide me, as to how I can make my test cover all the possible code. I am not supposed to change my code for the test.
I think you got confused with the lamba expression, and believe me it is very confusing in the beginning. But once you are fluent with it, it will be a breeze.
So here you got the instance of CommandLineRunner from method registerStartersAndReaders call, and your assertNotNull PASS as you have the not null instance, but until you call the run method of FunctionalInterface nothing will be executed.
Add runner.run(args) to execute the method(s) in your test case.

How do I manage unit test resources in Kotlin, such as starting/stopping a database connection or an embedded elasticsearch server?

In my Kotlin JUnit tests, I want to start/stop embedded servers and use them within my tests.
I tried using the JUnit #Before annotation on a method in my test class and it works fine, but it isn't the right behaviour since it runs every test case instead of just once.
Therefore I want to use the #BeforeClass annotation on a method, but adding it to a method results in an error saying it must be on a static method. Kotlin doesn't appear to have static methods. And then the same applies for static variables, because I need to keep a reference to the embedded server around for use in the test cases.
So how do I create this embedded database just once for all of my test cases?
class MyTest {
#Before fun setup() {
// works in that it opens the database connection, but is wrong
// since this is per test case instead of being shared for all
}
#BeforeClass fun setupClass() {
// what I want to do instead, but results in error because
// this isn't a static method, and static keyword doesn't exist
}
var referenceToServer: ServerType // wrong because is not static either
...
}
Note: this question is intentionally written and answered by the author (Self-Answered Questions), so that the answers to commonly asked Kotlin topics are present in SO.
Your unit test class usually needs a few things to manage a shared resource for a group of test methods. And in Kotlin you can use #BeforeClass and #AfterClass not in the test class, but rather within its companion object along with the #JvmStatic annotation.
The structure of a test class would look like:
class MyTestClass {
companion object {
init {
// things that may need to be setup before companion class member variables are instantiated
}
// variables you initialize for the class just once:
val someClassVar = initializer()
// variables you initialize for the class later in the #BeforeClass method:
lateinit var someClassLateVar: SomeResource
#BeforeClass #JvmStatic fun setup() {
// things to execute once and keep around for the class
}
#AfterClass #JvmStatic fun teardown() {
// clean up after this class, leave nothing dirty behind
}
}
// variables you initialize per instance of the test class:
val someInstanceVar = initializer()
// variables you initialize per test case later in your #Before methods:
var lateinit someInstanceLateZVar: MyType
#Before fun prepareTest() {
// things to do before each test
}
#After fun cleanupTest() {
// things to do after each test
}
#Test fun testSomething() {
// an actual test case
}
#Test fun testSomethingElse() {
// another test case
}
// ...more test cases
}
Given the above, you should read about:
companion objects - similar to the Class object in Java, but a singleton per class that is not static
#JvmStatic - an annotation that turns a companion object method into a static method on the outer class for Java interop
lateinit - allows a var property to be initialized later when you have a well defined lifecycle
Delegates.notNull() - can be used instead of lateinit for a property that should be set at least once before being read.
Here are fuller examples of test classes for Kotlin that manage embedded resources.
The first is copied and modified from Solr-Undertow tests, and before the test cases are run, configures and starts a Solr-Undertow server. After the tests run, it cleans up any temporary files created by the tests. It also ensures environment variables and system properties are correct before the tests are run. Between test cases it unloads any temporary loaded Solr cores. The test:
class TestServerWithPlugin {
companion object {
val workingDir = Paths.get("test-data/solr-standalone").toAbsolutePath()
val coreWithPluginDir = workingDir.resolve("plugin-test/collection1")
lateinit var server: Server
#BeforeClass #JvmStatic fun setup() {
assertTrue(coreWithPluginDir.exists(), "test core w/plugin does not exist $coreWithPluginDir")
// make sure no system properties are set that could interfere with test
resetEnvProxy()
cleanSysProps()
routeJbossLoggingToSlf4j()
cleanFiles()
val config = mapOf(...)
val configLoader = ServerConfigFromOverridesAndReference(workingDir, config) verifiedBy { loader ->
...
}
assertNotNull(System.getProperty("solr.solr.home"))
server = Server(configLoader)
val (serverStarted, message) = server.run()
if (!serverStarted) {
fail("Server not started: '$message'")
}
}
#AfterClass #JvmStatic fun teardown() {
server.shutdown()
cleanFiles()
resetEnvProxy()
cleanSysProps()
}
private fun cleanSysProps() { ... }
private fun cleanFiles() {
// don't leave any test files behind
coreWithPluginDir.resolve("data").deleteRecursively()
Files.deleteIfExists(coreWithPluginDir.resolve("core.properties"))
Files.deleteIfExists(coreWithPluginDir.resolve("core.properties.unloaded"))
}
}
val adminClient: SolrClient = HttpSolrClient("http://localhost:8983/solr/")
#Before fun prepareTest() {
// anything before each test?
}
#After fun cleanupTest() {
// make sure test cores do not bleed over between test cases
unloadCoreIfExists("tempCollection1")
unloadCoreIfExists("tempCollection2")
unloadCoreIfExists("tempCollection3")
}
private fun unloadCoreIfExists(name: String) { ... }
#Test
fun testServerLoadsPlugin() {
println("Loading core 'withplugin' from dir ${coreWithPluginDir.toString()}")
val response = CoreAdminRequest.createCore("tempCollection1", coreWithPluginDir.toString(), adminClient)
assertEquals(0, response.status)
}
// ... other test cases
}
And another starting AWS DynamoDB local as an embedded database (copied and modified slightly from Running AWS DynamoDB-local embedded). This test must hack the java.library.path before anything else happens or local DynamoDB (using sqlite with binary libraries) won't run. Then it starts a server to share for all test classes, and cleans up temporary data between tests. The test:
class TestAccountManager {
companion object {
init {
// we need to control the "java.library.path" or sqlite cannot find its libraries
val dynLibPath = File("./src/test/dynlib/").absoluteFile
System.setProperty("java.library.path", dynLibPath.toString());
// TEST HACK: if we kill this value in the System classloader, it will be
// recreated on next access allowing java.library.path to be reset
val fieldSysPath = ClassLoader::class.java.getDeclaredField("sys_paths")
fieldSysPath.setAccessible(true)
fieldSysPath.set(null, null)
// ensure logging always goes through Slf4j
System.setProperty("org.eclipse.jetty.util.log.class", "org.eclipse.jetty.util.log.Slf4jLog")
}
private val localDbPort = 19444
private lateinit var localDb: DynamoDBProxyServer
private lateinit var dbClient: AmazonDynamoDBClient
private lateinit var dynamo: DynamoDB
#BeforeClass #JvmStatic fun setup() {
// do not use ServerRunner, it is evil and doesn't set the port correctly, also
// it resets logging to be off.
localDb = DynamoDBProxyServer(localDbPort, LocalDynamoDBServerHandler(
LocalDynamoDBRequestHandler(0, true, null, true, true), null)
)
localDb.start()
// fake credentials are required even though ignored
val auth = BasicAWSCredentials("fakeKey", "fakeSecret")
dbClient = AmazonDynamoDBClient(auth) initializedWith {
signerRegionOverride = "us-east-1"
setEndpoint("http://localhost:$localDbPort")
}
dynamo = DynamoDB(dbClient)
// create the tables once
AccountManagerSchema.createTables(dbClient)
// for debugging reference
dynamo.listTables().forEach { table ->
println(table.tableName)
}
}
#AfterClass #JvmStatic fun teardown() {
dbClient.shutdown()
localDb.stop()
}
}
val jsonMapper = jacksonObjectMapper()
val dynamoMapper: DynamoDBMapper = DynamoDBMapper(dbClient)
#Before fun prepareTest() {
// insert commonly used test data
setupStaticBillingData(dbClient)
}
#After fun cleanupTest() {
// delete anything that shouldn't survive any test case
deleteAllInTable<Account>()
deleteAllInTable<Organization>()
deleteAllInTable<Billing>()
}
private inline fun <reified T: Any> deleteAllInTable() { ... }
#Test fun testAccountJsonRoundTrip() {
val acct = Account("123", ...)
dynamoMapper.save(acct)
val item = dynamo.getTable("Accounts").getItem("id", "123")
val acctReadJson = jsonMapper.readValue<Account>(item.toJSON())
assertEquals(acct, acctReadJson)
}
// ...more test cases
}
NOTE: some parts of the examples are abbreviated with ...
Managing resources with before/after callbacks in tests, obviously, has it's pros:
Tests are "atomic". A test executes as a whole things with all the callbacks One won't forget to fire up a dependency service before the tests and shut it down after it's done. If done properly, executions callbacks will work on any environment.
Tests are self-contained. There is no external data or setup phases, everything is contained within a few test classes.
It has some cons too. One important of them is that it pollutes the code and makes the code violate single responsibility principle. Tests now not only test something, but perform a heavyweight initialization and resource management. It can be ok in some cases (like configuring an ObjectMapper), but modifying java.library.path or spawning another processes (or in-process embedded databases) are not so innocent.
Why not treat those services as dependencies for your test eligible for "injection", like described by 12factor.net.
This way you start and initialize dependency services somewhere outside of the test code.
Nowadays virtualization and containers are almost everywhere and most developers' machines are able to run Docker. And most of the application have a dockerized version: Elasticsearch, DynamoDB, PostgreSQL and so on. Docker is a perfect solution for external services that your tests need.
It can be a script that runs is run manually by a developer every time she wants to execute tests.
It can be a task run by build tool (e.g. Gradle has awesome dependsOn and finalizedBy DSL for defining dependencies). A task, of course, can execute the same script that developer executes manually using shell-outs / process execs.
It can be a task run by IDE before test execution. Again, it can use the same script.
Most CI / CD providers have a notion of "service" — an external dependency (process) that runs in parallel to your build and can be accessed via it's usual SDK / connector / API: Gitlab, Travis, Bitbucket, AppVeyor, Semaphore, …
This approach:
Frees your test code from initialization logic. Your tests will only test and do nothing more.
Decouples code and data. Adding a new test case can now be done by adding new data into dependency services with it's native toolset. I.e. for SQL databases you'll use SQL, for Amazon DynamoDB you'll use CLI to create tables and put items.
Is closer to a production code, where you obviously do not start those services when your "main" application starts.
Of course, it has it's flaws (basically, the statements I've started from):
Tests are not more "atomic". Dependency service must be started somehow prior test execution. The way it is started may be different in different environments: developer's machine or CI, IDE or build tool CLI.
Tests are not self-contained. Now your seed data may be even packed inside an image, so changing it may require rebuilding a different project.

ASP.NET MVC2 Custom View Engine ignored in unit tests

I'm trying to unit test a controller that stuffs data into a ViewData. All our views require similar data (Customer info which is derived from the url). So instead of putting the call into every single controller method, the original developers chose to put this ViewData stuffing into the OnActionExecuting event.
Of course, when you invoke the controller's action from a unit test, OnActionExecuting doesn't fire. (Thanks MVC Team!)
So I tried creating a custom view engine and having it stuff the customer data into the controllerContext when the view is requested. This works fine in a browser, but my viewEngine is ignored when I run this test. No amount of ViewEngines.Add(new funkyViewEngine) has any effect.
[TestMethod()]
public void LoginTest()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new FunkyViewEngine());
UserController target = new UserController();
target.SetStructureMap(); <--sets us to use the test repo
target.ControllerContext.HttpContext = MVCHelpers.FakeHttpContext("https://customersubdomain.ourdomain.com"); <--moq magic
var actual = target.Login();
Assert.IsTrue(actual.GetType().IsAssignableFrom(typeof(System.Web.Mvc.ViewResult)));
var vr = actual as ViewResult;
Assert.IsTrue(vr.ViewData.Community() != null); <--"Community" should be set by viewengine
Assert.IsTrue(vr.ViewData.Community().Subdomain == "customersubdomain.ourdomain");
Assert.IsTrue(vr.ViewData.Community().CanRegister);
}
Is there any hope here? How do I either 1) create a method that gets called on controller execution BOTH in the browser and the unit framework or 2) get the unit framework to invoke my view engine.
Sorry for your frustration. The reason why you are seeing OnActionExecuting not being called when you directly call your action method from the unit test is because that's not how things work in MVC.
The request gets executed via a "pipeline", which as far as this area is concerned consists of the ControllerActionInvoker. This class is responsible for:
Finding the action method
Invoking action filters' OnActionExecuting method (note: your controller class is also an action filter)
Calling the action method itself
Invoking the action filters' OnActionExecuted method
Handling the result (e.g. finding the view and rendering it)
In your unit test you are directly invoking step 3. and skipping all the other steps. In a unit test, it is your responsibility to call any setup code required for your action to work.
However, this does not mean you should now write unit tests that use the ControllerActionInvoker to execute the entire pipeline. We (the MVC team) have already verified that all the pieces work together.
Instead, you should test your specific application code. In this case, you might consider having the following unit tests:
A test that verifies that given some Url calling OnActionExecuting on your controller puts the right Customer object into ViewData
A test that verifies that given some Customer object present in ViewData your action method returns the appropriate result
My last point is that you should keep the functionality in OnActionExecuting. A custom view engine is definetely the wrong place for it.
Not an answer you're probably looking for, but I'm using a custom MvcHandler to achieve the same goal (getting customer from URL in multi-tenant app). ViewEngine doesn't sound like a good place for this kind of logic to me...
My custom handler looks more or less like this:
public class AccountMvcHandler : MvcHandler
{
public Account Account { get; private set; }
protected override IAsyncResult BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, object state)
{
return base.BeginProcessRequest(httpContext, callback, state);
}
protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
{
string accountName = this.RequestContext.RouteData.GetRequiredString("account");
Account = ServiceFactory.GetService<ISecurityService>().GetAccount(accountName);
return base.BeginProcessRequest(httpContext, callback, state);
}
}