Unit Testing local function in Lua - unit-testing

So I'm using Busted to create unit tests for an existing Lua file, without changing the code in the file if possible. The file imports another file, and then stores various methods from that file in local functions, like so.
[examplefile.lua]
local helper = require "helper.lua"
local helper_accept = helper.accept
local helper_reject = helper.reject
foo = new function()
-- do something which uses helper_accept
-- do something which uses helper_reject
end
I want to spy on these methods in my tests to ensure that they have been called at the right places. However, I can't find any way to do this from the test.
I've tried simply mocking out the helper methods, as in:
[exampletest.lua]
local helper = require "helper.lua"
local examplefile = require "examplefile.lua"
-- mock the helper function to simply return true
helper.accept = new function() return true end
spy.on(helper, "accept")
examplefile:foo
assert.spy(helper).was().called()
but that doesn't work as the real file uses the helper_accept and helper_reject methods, not helper.accept and helper.reject.
Can this be done without changing the code?
Thanks.

The easiest way I can think of for accomplishing this is to override the "helper" library with hook stubs. You can do this by modifying the package.loaded table. The package.loaded table stores the result of an initial call to require "lib", so that if the same require is called again, the module does not need to be reloaded. If you place something in there before the first call to require "lib", it will never actually load the library from the filesystem.
In your case you may want to actually load the library, but hook all the library accesses. I'd do that something like this...
local lib = require "lib"
local function hook_func(_, key)
print('Accessing "lib" attribute '..tostring(key))
-- other stuff you might want to do in the hook
return lib[key]
end
package.loaded["lib"] = setmetatable({}, {__index = hook_func})

Related

Ensuring a sandboxed mock refers to the same module instance as the Jest environment already has loaded

This is a bit hairy, so bare with me for a second :) Our Jest environment, custom-env, requires a module A and sets adds a function to the global scope using this.global.getBar = A.getBar.
The custom environment is used by a test. This test has a dependency to another module B, which is mocked out using jest.mock('../../moduleB', () => require('./FakeModuleB')). FakeModuleB is using the methods on module A.
Module A looks like this:
const bar = generateUuid();
module.exports = { getBar(){ return bar; } }
The weird thing here is that what is returned by getBar() differs depending on whether or not it is loaded through jest.mock() or loaded by the Jest environment. Essentially, jest.mock() seems to have cleared the loading cache somehow, so it loads the module afresh, which makes me end up with two instances of the module.
I am wondering what the "right" way of handling this could be?
The hackish way is of course to realize what this is and expose a reference to the loaded module on the global scope and refer to that in the require calls in ./FakeModuleB (which is loaded by jest.mock()):
// import { getBar } from '../../A'
const { getBar } = global.aModule;
I have then also exposed them in the jest env setup() method:
const { getBar } = aModule
this.global.aModule = aModule
this.global.getBar = getBar
Of course, I do not like this approach, polluting the global namespace for the sake of hacking around loader issues, but I am not sure how to approach this in another way.

Xcode restore files in bundle between unit tests

I'm writing a series of unit tests for a class that requires a property list stored in the bundle. I keep a mock version of this property list in my unit test target and inject the unit test bundle into the class such that it can be read. One of my unit test deals with handling the case where the file cannot be found, so I simply delete it from the bundle like so:
NSString *plistPath = [self.bundle pathForResource:kInAppPurchasesPlistName ofType:#"plist"];
[[NSFileManager defaultManager] removeItemAtPath:plistPath error:nil];
However this leads to problems as the file is now deleted from the bundle, even between tests. If I set my tests up correctly this may not be an issue, but with randomized execution order it is.
I do "recreate" the bundle between unit tests:
- (void)setUp {
[...]
self.bundle = [NSBundle bundleForClass:[self class]];
[...]
}
- (void)tearDown {
[...]
self.bundle = nil;
[...]
}
Although I'm suspecting that the underlying bundle does not change or reset state by doing this.
What's the best way of accomplishing this? In summary, I need a way that will allow me to "inject" a fake file into my class which reads it from the bundle. I want to delete this file in some tests, but for the state to be completely reset after each individual test.
Tests should be isolated so that you can run them individually, or in any order. If a test actually deletes something, you'll have to put it back.
The danger of making changes to the file system is that it's persistent mutable state, shared across tests. Instead of talking directly to the NSFileManager, I recommend injecting it instead. Depending on your code, this could be done through an initialization parameter (preferred) or a property (second best). You can even have your production code use a lazy property so that it uses [NSFileManager defaultManager] by default, unless a different instance has been injected.
To inject a fake version of NSFileManager that your tests can control, I recommend using OCMockito or OCMock.

How can I test functions inside a single file Lua script?

I would like to unit test functions from a single file Lua script, say script.lua. The script looks something like follows:
-- some fields from gvsp dissector which shall be post processed in custom dissector
gvsp_field0_f = Field.new("gvsp.<field0-name>")
gvsp_field1_f = Field.new("gvsp.<field1-name>")
-- custom protocol declaration
custom_protocol = Proto("custom","Custom Postdissector")
-- custom protocol field declarations
field0_f = ProtoField.string("custom.<field0-name>","Custom Field 0")
field1_f = ProtoField.string("custom.<field1-name>","Custom Field 1")
-- register custom protocol as postdissector
register_postdissector(custom_protocol)
function custom_protocol.dissector(buffer,pinfo,tree)
-- local field values of "pre" dissector which are analyzed
local gvsp_field0_value = gvsp_field0_f()
local gvsp_field1_value = gvsp_field1_f()
-- functions which shell be unit tested
function0(...)
function1(...)
end
function0(...)
-- implementation
end
function1(...)
-- implementation
end
Let's say I do not want to separate the functions from the script file into a separate module file (which would probably make things easier). How can I define tests (preferably with luaunit because easy to integrate, but other tool would be ok as well) for the functions defined in script.lua inside the script.lua file or in a separate test_script.lua file?
To enable separate script and unit test execution one needs at least 3 files (in this example 4 because the unit test framework luaunit which consists of a single file is integrated into the project directory). For this example all files reside in the same directory. The script script.lua may not define any functions in it but must import all functions it needs from its module module.lua.
-- script imports module functions
module = require('module')
-- ... and uses it to print the result of the addition function
result = module.addtwo(1,1)
print(result)
module.lua is implemented accoring to the Lua module skeleton that its functions are automatically registered for import through other script files or modules.
-- capture the name searched for by require
local NAME=...
-- table for our functions
local M = { }
-- A typical local function that is also published in the
-- module table.
local function addtwo(a,b) return a+b end
M.addtwo = addtwo
-- Shorthand form is less typing and doesn't use a local variable
function M.subtwo(x) return x-2 end
return M
test_module.lua contains the unit tests for the module functions and imports luaunit.lua (unit test framework) for its execution. test_module.lua has the following content.
luaunit = require('luaunit')
script = require('module')
function testAddPositive()
luaunit.assertEquals(module.addtwo(1,1),2)
end
os.exit( luaunit.LuaUnit.run() )
If you run the tests by executing lua test_module.lua the tests are executed separately from the script functionality.
.
Ran 1 tests in 0.000 seconds, 1 success, 0 failures
OK
The script is executed as usual with lua script.lua with output 2.
Simple answer: You can't!
I've asked the Lua team about this myself a few years ago as there is no obvious way for a script to know if it is the main script running or included (e.g., 'require'd).
There does not seem to be interest for adding such capability in the foreseeable future, either!

Mocking a dependency in Node

I'm in the process of learning Node.js and am wondering about how people mock dependencies in their modules when unit testing.
For example:
I have a module that abstracts my MongoDB calls. A module that uses this module may start out something like this.
var myMongo = require("MyMongoModule");
// insert rest of the module here.
I want to ensure I test such a module in isolation while also ensuring that my tests don't insert records/documents into Mongo.
Is there a module/package that I can use that proxies require() so I can inject in my own mocks? How do other's typically address this issue?
You can use a dependency injection library like nCore
To be honest, the hard part of this is actually mocking out the mongoDB API, which is complex and non trivial. I estimate it would take about a week to mock out most of the mongo API I use so I just test againts the a local mongodb database on my machine (which is always in a weird state)
Then with nCore specific syntax
// myModule.js
module.exports = {
myMethod: function () {
this.mongo.doStuff(...)
},
expose: ["myMethod"]
};
// test-myModule.js
var module = require("myModule")
module.mongo = mongoMock
assert(module.myMethod() === ...)
After reviewing Ryanos's suggestion as well as the Horaa package on npm, I discovered this thread on the Google Group that pointed me towards Sandboxed-Module.
Sandboxed-Module allows me to inject/override require() without me having to expose such dependencies for my unit tests.
I'm still up for other suggestions; however, Sandboxed-Module appears to fit my needs at the moment.
You easily mock require by using "a": https://npmjs.org/package/a
e.g. need to mock require('./foo') in unit test:
var fakeFoo = {};
var expectRequire = require('a').expectRequire;
expectRequire('./foo).return(fakeFoo);
//in sut:
var foo = require('./foo); //returns fakeFoo
Overwriting require to inject your mocks is a possible solution. However, I concur in Raynos' opinion:
I personally find the methodology of overwriting require on a file by file basis an "ugly hack" and prefer to go for proper DI. It is however optimum for mocking one or two modules on an existing code base without rewriting code for DI support.
To use proper dependency injection not only saves you an "ugly hack" but also allows you to apply additional use cases apart from injecting mocks. In production you may e.g. usually instantiate connections over http and in certain circumstances inject a different implementation to establish a connection over VPN.
If you want to look for a dependency injection container read this excellent article and check out Fire Up! which I implemented.

fake directories for .net unit testing

I'm trying to create a unit test for a code similar to this:
foreach (string domainName in Directory.GetDirectories(server.Path))
{
HandleDomainDirectory(session, server, domainName);
}
The problem is that I'm using the System.IO.Directory class in my code.
How can I create a testing method that won't be dependent on any folder I have on my hard disk.
In other words, How can I fake the response of "Directory.GetDirectories(server.Path)"?
(Please note, I do control the "server" object in my class, therefore i can give any path i want)
Thanks.
Rather than calling Directory.GetDirectories(server.Path) directly, you could create an interface like IDirectoryResolver with a single method that takes a path string and returns the list of directories. The class containing your code above would then need a property or field of type IDirectoryResolver, which can be injected through the constructor or a setter.
For your production code, you would then create a new class that implements the IDirectoryResolver interface. This class could use the Directory.GetDirectories method in its implementation of the interface method.
For unit testing, you could create a MockDirectoryResolver class which implements IDirectoryResolver (or use a mocking library to create a mock instance for the interface). The mock implementation can do whatever you need it to do.
You would inject a wrapper class.
public class DirectoryFetcher
{
public virtual List<string> GetDirectoriesIn(string directory)
{
return Directory.GetDirectories(directory);
}
}
And then inject that:
foreach(string directory in _directoryFetcher.GetDirectoriesIn(server.Path))
{
// Whatever
}
You can then Mock that guy at the injection point (this example uses Moq, and constructor injection):
Mock<DirectoryFetcher> mockFetcher = new Mock<DirectoryFetcher>();
mockFetcher.Setup(x => x.GetDirectoriesIn("SomeDirectory")).Returns(new List<string>
{
"SampleDirectory1",
"SampleDirectory2"
});
MyObjectToTest testObj = new MyObjectToTest(mockFetcher.Object);
// Do Test
When communicating with the outside world, such as file system, databases, web services etc. , you should always consider using wrapper classes like the others before me suggested. Testability is one major argument, but an even bigger one is: The out side world changes, and you have no control over it. Folders move, user rights changes, new disk drives appears and old ones are removed. You only want to care about stuff like that in one place. Hence, the wrapper -- let's call it DirectoryResolver like Andy White suggested ealier.
So, wrap your file system calls, extract an interface, and inject that interface where you need to communicate with the file system.
The best solution I've found was to use Moles. The code is very specific, and must do very specific thing. Wrapping it with wrapper class will be redundant. The only reason I needed wrapper class is in order to write tests. Moles allows me to write the tests without any wrapper class :)