Run unit tests on dynamically created DLL - unit-testing

I am thinking on how to implement this , and seems like my knowledge is too poor to understand the implementation.
I have a code that compiles source code to DLL.
Then I need somehow to run Unit test on this Dll , and check 3-4 methods inside.
I am trying to run unit tests this way.
CompilerResults compileResults = codeProvider.CompileAssemblyFromSource(compilerParameters, new string[] { sourceCode });
Assembly myAssembly = compileResults.CompiledAssembly;
TestPackage testPackage = new TestPackage(#"TestingProject.dll");
testPackage.Assemblies.Add(myAssembly);
RemoteTestRunner remoteTestRunner = new RemoteTestRunner();
remoteTestRunner.Load(testPackage);
TestResult testResult = remoteTestRunner.Run(new NullListener(),TestFilter.Empty,false,LoggingThreshold.All);
And this for example Test
[Test]
public void AddTest(IDynamicScript s)
{
Assert.AreEqual(10, s.Add(5,5));
Assert.AreNotEqual(10,s.Add(4,5));
}
Since Assembly is compiled dynamically , I can't reference it to unit test Project , and it will not compile , any suggestions please on how to implement this please

Your code works just fine after a few modifications. These are the required changes:
The test code needs to be wrapped in a class with appropriate namespace imports, you can't compile standalone methods with the C# compiler
You need to inform the compiler about the assembly references of the code you're compiling, in this case I supplied the path to the nunit.framework.dll assembly, which I got from the location of the copy loaded in the main AppDomain, but you can also reference it from the file system without loading it. Usually you will also need to supply the paths of the assemblies containing the code you're testing
The constructor of the TestPackage class takes an absolute path in its constructor, in this case I supplied the location of the generated assembly
This is the code with the corrections:
var sourceCode = #"
using NUnit.Framework;
public class Fixture
{
[Test]
public void AddTest()
{
Assert.AreEqual(10, 5+5);
}
}";
var provider = new CSharpCodeProvider();
CompilerResults compileResults = provider.CompileAssemblyFromSource(
new CompilerParameters(new[]{ typeof(TestAttribute).Assembly.Location }),
new[]{ sourceCode });
var assembly = compileResults.CompiledAssembly;
var package = new TestPackage(assembly.Location);
var runner = new RemoteTestRunner();
runner.Load(package);
var result = runner.Run(new NullListener(),
TestFilter.Empty,
false,
LoggingThreshold.All);

Related

Sitecore 9.2 Unit Test Error: Could not find configuration node: contentSearch/configuration

I am trying to configure a Unit Test project within my Feature directory i.e.
Feature
Activity
ExampleProject
ExampleProject.UnitTest
Implementation
In Unit Test Project: UnitTest.cs [TestMethod]
{
string val1= "Search";
string val2= "en";
string expectedVal = "xyz";
string retVal = new Test.GetItem(val1, val2);
Assert.AreEqual(expectedVal, retVal);
}
In Implementation Class
public string GetItem(str1, str2)
{
List<SearchResultItem> matches;
--BREAKS HERE-- using (var context = ContentSearchManager.GetIndex("sitecore_web_index").CreateSearchContext())
{
var predicate = PredicateBuilder.True<SearchResultItem>();
predicate = predicate.And(p => p.Path.StartsWith("/sitecore/system/Dictionary"));
predicate = predicate.And(p => p.str1== str2);
matches = context.GetQueryable<SearchResultItem>().Where(predicate).ToList();
}
}
I believe I have all necessary dependencies referenced (Sitecore.Kernel, Sitecore.Mvc, Sitecore.ContentSearch) but I am still getting error: Could not find configuration node: contentSearch/configuration. I have local IIS instance of my Sitecore site working where GetItem(str1, str2) is being called multiple times so not sure why a Unit Test project won't run properly.
Versions
Sitecore 9.2
.NET 4.7.2
Do I still have to make changes to config to allow for Unit Test?
Any help is appreciated, thanks.
The problem you are facing is caused by consuming static code (aka hidden dependency) - contentSearchManager inside the test.
You'll need to use a wrapper in your code that would proxy the static code calls. The same approach is used in Sitecore.Services.Infrastructure.Sitecore.Services.IContentSearchManagerWrapper for Sitecore.Services.Infrastructure.Sitecore.dll in Sitecore 9.3. The implementation simply invokes static code in Sitecore.Services.Infrastructure.Sitecore.Services.ContentSearchManagerWrapper.
You could reverse-engineer the code to see the actual impl.
Please also take a look at the article showing how to unit test Sitecore.

ASP.NET Web API Unit Test Autofac Module with BuildManager.GetReferencedAssemblies()

Working on a project in ASP.NET Web API 2 which has Autofac as my IoC container. This project is hosted on IIS and in my Autofac module I use the following method to scan for assemblies:
var asm = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
Why?
https://docs.autofac.org/en/latest/register/scanning.html#iis-hosted-web-applications
But now we are making Unit Tests using NUnit, during my setup I register my module which uses this method. Now I receive the following exception when running my tests:
System.InvalidOperationException: 'This method cannot be called during the application's pre-start initialization phase.'
I understand why I have this exception but I don't have a clue how to make my code work in tests and for deployment environments.
Setup method of NUnit:
[TestFixture]
public abstract class ApplicationTestBase
{
[SetUp]
public override void Init()
{
var builder = new ContainerBuilder();
// If the class requires auto mapper mapping, initialize them
// We do this in order not to init them for every test => optimalisation!
if (GetType().GetCustomAttributes<RequiresAutoMapperMappingsAttribute>(false) != null)
{
builder.RegisterModule<AutoMapperModule>();
}
this.Container = builder.Build();
}
}
Do I need to create a new module specific for my Unit tests or is there another way for this?
AutoMapperTest
[RequiresAutoMapperMappings]
[TestFixture]
public class AutoMapperTests : ApplicationTestBase
{
[Test]
public void Assert_Valid_Mappings()
{
Mapper.AssertConfigurationIsValid();
}
}
UPDATE
Like Cyril mentioned: Why do you need Ioc in your unit tests? I went searching and indeed you don't have to use the Ioc in your tests. So I ditched the Ioc and initialized my mapper configuration byy doing:
Mapper.Initialize(configuration =>
{
var asm = AppDomain.CurrentDomain.GetAssemblies()
.Where(a => a.FullName.StartsWith("ProjectWebService."));
configuration.AddProfiles(asm);
});
I would recommend separating the "how to load assemblies" logic from the "do assembly scanning and register modules logic."
Right now I'm guessing you have something like this all in one method.
public IContainer BuildContainer()
{
var asm = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(asm);
var container = builder.Build();
}
Not exactly that, but something similar - the loading of assemblies is inlined and directly used.
Separate that so you can swap that logic in for testing. For example, consider allowing a parameter to be optionally passed so you can override the logic in test.
public IContainer BuildContainer(Func<IEnumerable<Assembly>> assemblyLoader = null)
{
IEnumerable<Assembly> asm = null;
if (assemblyLoader != null)
{
asm = assemblyLoader();
}
else
{
asm = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
}
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(asm);
var container = builder.Build();
}
Your default logic will work the way you want, but then in testing you can swap in something else.
var container = BuildContainer(() => AppDomain.GetAssemblies());
There are lots of ways you can do that swap-in. It could be anything from a static property you can set somewhere to a virtual method you can override somewhere. The point is, by separating the assembly loading logic you can get the test-time behavior to work but still use the registration behavior you're after.

Unity 5.6 : Unit test does not appear in "TestRunner">"Play Mode"

When I write a unit test, it properly appears in "TestRunner">"EditMode", but not in "TestRunner">"PlayMode". I have enabled the playmode, but it seems to not recognize my script.
the script is in a folder named "Editor"
the script can be run into the "EditMode", resulting in "EditMode test can only yield null" ( wich makes sense as this script calls "WaitForFixedUpdate()" )
I tried to do it in a new project, resulting in the same situation : unit tests cannot be run in Play Mode.
This is basic unit test code from unity doc : https://docs.google.com/document/d/1SeNOAVYaq9HUjsKAC2ZvRwKLD2MCNyV4LwcsP3BXm0s/edit
[UnityTest]
public IEnumerator GameObject_WithRigidBody_WillBeAffectedByPhysics()
{
var go = new GameObject();
go.AddComponent<Rigidbody>();
var originalPosition = go.transform.position.y;
yield return new WaitForFixedUpdate();
Assert.AreNotEqual(originalPosition, go.transform.position.y);
}
Unity version : 5.6.0f3
Did anyone met this problem before ?
Did I missed a step into Unit Test creation ?
Thanks

Using MPI.Net causes VS2012 unit test to fail when run, but succeed when debugged

I'm using MPI.Net for a Visual Studio 2012 project. All the unit tests (standard Microsoft Unit test project) fail if they are run, but succeed when they are debugged. I created a dummy project that has a single class (that just returns "foo") and have replicated the issue. It appears that the MPI environment is finalized before I actually do anything. I've tried adding a Sleep in the appropriate place to see if it was timing issues, but it seems to be something else. Has anyone had any experience with this?
My test method is:
[TestMethod]
public void TestMethod1()
{
string[] args = null;
using (MPI.Environment mpiEnv = new MPI.Environment(ref args))
{
if (MPI.Environment.Finalized)
{
throw new Exception("mpi finalized");
}
else
{
MPIdotNetUnitTestIssue.Class1 bar = new MPIdotNetUnitTestIssue.Class1();
Assert.AreEqual("foo", bar.Foo());
}
}
}
The exception occurs if the test is "run", the test passes if it is "debugged", even with no breakpoints.

Testing Node.js, mock out and test a module that has been required?

I am struggling to write high quality tests around my node modules. The problem is the require module system. I want to be able to check that a certain required module has a method or its state has changed. There seem to be 2 relatively small libraries which can be used here: node-gently and mockery. However, due to their low 'profile' it makes me think that either people don't test this, or there is another way of doing this that I am not aware of.
What is the best way to mock out and test a module that has been required?
----------- UPDATE ---------------
node-sandbox works on the same principals as stated below but is wrapped up in a nice module. I am finding it very nice to work with.
--------------- detailed awnser ---------------
After much trial I have found the best way to test node modules in isolation while mocking things out is to use the method by Vojta Jina to run each module inside of a vm with a new context as explained here.
with this testing vm module:
var vm = require('vm');
var fs = require('fs');
var path = require('path');
/**
* Helper for unit testing:
* - load module with mocked dependencies
* - allow accessing private state of the module
*
* #param {string} filePath Absolute path to module (file to load)
* #param {Object=} mocks Hash of mocked dependencies
*/
exports.loadModule = function(filePath, mocks) {
mocks = mocks || {};
// this is necessary to allow relative path modules within loaded file
// i.e. requiring ./some inside file /a/b.js needs to be resolved to /a/some
var resolveModule = function(module) {
if (module.charAt(0) !== '.') return module;
return path.resolve(path.dirname(filePath), module);
};
var exports = {};
var context = {
require: function(name) {
return mocks[name] || require(resolveModule(name));
},
console: console,
exports: exports,
module: {
exports: exports
}
};
vm.runInNewContext(fs.readFileSync(filePath), context);
return context;
};
it is possible to test each module with its own context and easily stub out all external dependencys.
fsMock = mocks.createFs();
mockRequest = mocks.createRequest();
mockResponse = mocks.createResponse();
// load the module with mock fs instead of real fs
// publish all the private state as an object
module = loadModule('./web-server.js', {fs: fsMock});
I highly recommend this way for writing effective tests in isolation. Only acceptance tests should hit the entire stack. Unit and integration tests should test isolated parts of the system.
I think the mockery pattern is a fine one. That said, I usually opt to send in dependencies as parameters to a function (similar to passing dependencies in the constructor).
// foo.js
module.exports = function(dep1, dep2) {
return {
bar: function() {
// A function doing stuff with dep1 and dep2
}
}
}
When testing, I can send in mocks, empty objects instead, whatever seems appropriate. Note that I don't do this for all dependencies, basically only IO -- I don't feel the need to test that my code calls path.join or whatever.
I think the "low profile" that is making you nervous is due to a couple of things:
Some people structure their code similar to mine
Some people have their own helper fulfilling the same objective as mockery et al (it's a very simple module)
Some people don't unit test such things, instead spinning up an instance of their app (and db, etc) and testing against that. Cleaner tests, and the server is so fast it doesn't affect test performance.
In short, if you think mockery is right for you, go for it!
You easily mock require by using "a": https://npmjs.org/package/a
//Example faking require('./foo') in unit test:
var fakeFoo = {};
var expectRequire = require('a').expectRequire;
expectRequire('./foo).return(fakeFoo);
//in sut:
var foo = require('./foo); //returns fakeFoo