The context
In a framework I'm currently building, I am using multiple structs (example) to store String constants. Let's say one looked like this:
public struct SpecificConstants {
private init() {}
public static let foo: String = "foo"
}
This is all nice and well. You can use the constant, it doesn't clutter global namespace, the struct name states the specific purpose of the constants which are defined in it.
Also, by making init() private, it is made clear inside the framework (it's open source) and outside of it that this struct should not be instantiated. It wouldn't hurt if you were to create an instance of it but it would also have no use at all. Also, the init would show up in autocomplete if it weren't private, which would annoy me :)
The problem
I'm proudly writing a lot of tests for the framework and I'm using Xcode's internal coverage reporting (llvm cov). Unfortunately, this coverage reporting shows the init as 'not covered':
This is completely logical, since the init isn't being run by the tests, because it can't be.
To my distress, this prevents me from getting the good ol' 100% coverage.
Possible solutions
I could use lcov, which would enable me to use LCOV_EXCL_LINE or LCOV_EXCL_START and LCOV_EXCL_STOP to exclude the inits from the coverage.
Why not: I'd love not having to setup a different coverage tool when there's already a builtin tool in Xcode.
I could make the inits internally accessible so I could gain access to them inside my unit tests by importing the module as #testable.
Why not: Though they would still be inaccessible from outside the framework, they would now be visible inside the framework, which I don't like. I'd like them to be darn private :D
I could live with my coverage never reaching 100%.
Why not: Because I just can't :).
The question
Is there any way (I could live with it being a bit, even quite hacky) to run this forsaken init in my unit tests while keeping it inaccessible from outside as well as inside the framework?
Move your String constants to an enum then you won't need a private init.
enum SpecificConstants {
static let foo = "foo"
}
Related
I use Autofac extensively. Recently I've gotten interested in tweaking the lifetime scopes when registering items for XUnit testing. Basically I want to register a number of standard components I use as "instance per test" rather than what I normally do for runtime (I've found a useful library on github that defines an instance-per-test lifetime).
One way to do this is to define two separate container builds, one for runtime and one for xunit testing. That would work but it gets increasingly expensive to maintain.
What I'd like to do (I think) is modify the registration pipeline dynamically depending upon the context -- runtime or xunit test -- in which it is being built. In pseudocode:
builder.RegisterType<SomeType>().AsImplementedInterfaces().SingleInstance();
...
void TweakPipeline(...)
{
if( Testing )
{
TypeBeingRegistered.InstancePerTest();
}
else
{
TypeBeingRegistered.SingleInstance();
}
}
Is this something Autofac middleware can do? If not is there another capability in the Autofac API which could address it? As always, links to examples would be appreciated.
This is an interesting question. I like that you started thinking about some of the new features in Autofac, very few do. So, kudos for the good question.
If you think about the middleware, yes, you can probably use it to muck with lifetime scope, but we didn't really make "change the lifetime scope on the fly" something easy to do and... I'll be honest, I'm not sure how you'd do it.
However, I think there are a couple of different options you have to make life easier. In the order in which I'd do them if it was me...
Option 1: Container Per Test
This is actually what I do for my tests. I don't share a container across multiple tests, I actually make building the container part of the test setup. For Xunit, that means I put it in the constructor of the test class.
Why? A couple reasons:
State is a problem. I don't want test ordering or state on singletons in the container to make my tests fragile.
I want to test what I deploy. I don't want something to test out OK only to find that it worked because of something I set up in the container special for testing. Obvious exceptions for mocks and things to make the tests actually unit tests.
If the problem is that the container takes too long to set up and is slowing the tests down, I'd probably troubleshoot that. I usually find the cause of this to be either that I'm assembly scanning and registering way, way too much (oops, forgot the Where statement to filter things down) or I've started trying to "multi-purpose" the container to start orchestrating my app startup logic by registering code to auto-execute on container build (which is easy to do... but don't forget the container isn't your app startup logic, so maybe separate that out).
Container per test really is the easiest, most isolated way to go and requires no special effort.
Option 2: Modules
Modules are a nice way to encapsulate sets of registrations and can be a good way to take parameters like this. In this case, I might do something like this for the module:
public class MyModule : Module
{
public bool Testing { get; set; }
protected override void Load(ContainerBuilder builder)
{
var toUpdate = new List<IRegistrationBuilder<object, ConcreteReflectionActivatorData, SingleRegistrationStyle>>();
toUpdate.Add(builder.RegisterType<SomeType>());
toUpdate.Add(builder.RegisterType<OtherType>());
foreach(var reg in toUpdate)
{
if(this.Testing)
{
reg.InstancePerTest();
}
else
{
reg.SingleInstance();
}
}
}
}
Then you could register it:
var module = new MyModule { Testing = true };
builder.RegisterModule(module);
That makes the list of registrations easier to tweak (foreach loop) and also keeps the "things that need changing based on testing" isolated to a module.
Granted, it could get a little complex in there if you have lambdas and all sorts of other registrations in there, but that's the gist.
Option 3: Builder Properties
The ContainerBuilder has a set of properties you can use while building stuff to help avoid having to deal with environment variables but also cart around arbitrary info you can use while setting up the container. You could write an extension method like this:
public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
EnableTesting<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registration,
ContainerBuilder builder)
{
if(builder.Properties.TryGetValue("testing", out var testing) && Convert.ToBoolean(testing))
{
registration.InstancePerTest();
}
return registration;
}
Then when you register things that need to be tweaked, you could do it like this:
var builder = new ContainerBuilder();
// Set this in your tests, not in production
// builder.Properties["testing"] = true;
builder.RegisterType<Handler>()
.SingleInstance()
.EnableTesting(builder);
var container = builder.Build();
You might be able to clean that up a bit, but again, that's the general idea.
You might ask why use the builder as the mechanism to transport properties if you have to pass it in anyway.
Fluent syntax: Due to the way registrations work, they're all extension methods on the registration, not on the builder. The registration is a self-contained thing that doesn't have a reference to the builder (you can create a registration object entirely without a builder).
Internal callbacks: The internals on how registration works basically boil down to having a list of Action executed where the registrations have all the variables set up in a closure. It's not a function where we can pass stuff in during build; it's self-contained. (That might be interesting to change, now I think of it, but that's another discussion!)
You can isolate it: You could put this into a module or anywhere else and you won't be adding any new dependencies or logic. The thing carting around the variable will be the builder itself, which is always present.
Like I said, you could potentially make this better based on your own needs.
Recommendation: Container Per Test
I'll wrap up by just again recommending container per test. It's so simple, it requires no extra work, there are no surprises, and it "just works."
I am developing a modular WPF application with Prism in .Net Core 5.0 (using MVVM, DryIoc) and I would like to have a module that is not a WPF module, i.e., a module with functionality that can be used by any other module. I don't want any project reference, because I want to keep the loosely coupled idea of the modules.
My first question is: is it conceptually correct? Or is it mandatory that a module has a screen? I guess it should be ok.
The second and more important (for me) is, what would be the best way to create the instance?
This is the project (I know I should review the names in this project):
HotfixSearcher is the main class, the one I need to get instantiated. In this class, for example, I subscribe to some events.
And this is the class that implements the IModule interface (the module class):
namespace SearchHotfix.Library
{
public class HotfixSearcherModule : IModule
{
public HotfixSearcherModule()
{
}
public void OnInitialized(IContainerProvider containerProvider)
{
//Create Searcher instance
var searcher = containerProvider.Resolve<IHotfixSearcher>();
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IHotfixSearcher, HotfixSearcher>();
}
}
}
That is the only way I found to get the class instantiated, but I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
For modules that have screens, the instances get created when navigating to them using the RequestNavigate method:
_regionManager.RequestNavigate(RegionNames.ContentRegion, "ContentView");
But since this is only a library with no screens, I can't find any other way to get this instantiated.
According to Prism documentation, subscribing to an event shoud be enough but I tried doing that from within my main class HotfixSearcher but it does not work (breakpoints on constructor or on the event handler of the event to which I subscribe are never hit).
When I do this way, instead, the instance is created, I hit the constructor breakpoint, and obviously the instance is subscribed to the event since it is done in the constructor.
To sum up, is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
Thanks in advance!
Or is it mandatory that a module has a screen?
No, of course not, modules have nothing to do with views or view models. They are just a set of registrations with the container.
what would be the best way to create the instance?
Let the container do the work. Normally, you have (at least) one assembly that only contains public interfaces (and the associated enums), but no modules. You reference that from the module and register the module's implementations of the relevant interfaces withing the module's Initialize method. Some other module (or the main app) can then have classes that get the interfaces as constructor parameters, and the container will resolve (i.e. create) the concrete types registered in the module, although they are internal or even private and completely unknown outside the module.
This is as loose a coupling as it gets if you don't want to sacrifice strong typing.
is there a way to get rid of that var searcher = containerProvider.Resolve<IHotfixSearcher>(); and a better way to achieve this?
You can skip the var searcher = part :-) But if the HotfixSearcher is never injected anywhere, it won't be created unless you do it yourself. OnInitialized is the perfect spot for this, because it runs after all modules had their chance to RegisterTypes so all dependencies should be registered.
If HotfixSearcher is not meant to be injected, you can also drop IHotfixSearcher and resolve HotfixSearcher directly:
public void OnInitialized(IContainerProvider containerProvider)
{
containerProvider.Resolve<HotfixSearcher>();
}
I am not a hundred per cent comfortable with creating an instance that is not used, I think it does not make much sense.
It is used, I suppose, although not through calling one of its methods. It's used by sending it an event. That's just fine. Think of it like Task.Run - it's fine for the task to exist in seeming isolation, too.
I'm looking for a way of condensing some of my AS3 code to avoid almost duplicate commands.
The issue is that I have multiple variables with almost the same name e.g. frenchLanguage, englishLanguage, germanLanguage, spanishLanguage
My Controller class contains public static variables (these are accessed across multiple classes) and I need a way to be able to call a few of these variables dynamically. If the variables are in the class you are calling them from you can do this to access them dynamically:
this["spanish"+"Language"]
In AS3 it's not possible to write something like:
Controller.this["spanish"+"Language"]
Is there any way to achieve this? Although everything is working I want to be able to keep my code as minimal as possible.
It is possible to access public static properties of a class this way (assuming the class name is Controller as in your example:
Controller['propertyName']
I'm not sure how this helps to have "minimal code", but this would be a different topic/question, which might need some more details on what you want to achive.
Having said that, I like the approach DodgerThud suggests in the comments of grouping similar values in a (dynamic) Object or Dictonary and give it a proper name.
Keep in mind, that if the string you pass in as the key to the class or dynamic object is created from (textual) user input you should have some checks for the validity of that data, otherwise your programm might crash or expose other fields to the user.
It would make sense to utilize a Dictionary object for a set of variables inherited: it provides a solid logic and it happens to work...
I do not think this is what you are trying to accomplish. I may be wrong.
Classes in AS3 are always wrapped within a package - this is true whether you have compiled from Flash, Flex, Air, or any other...
Don't let Adobe confuse you. This was only done in AS3 to use Java-Based conventions. Regardless, a loosely typed language is often misunderstood, unfortunately. So:
this["SuperObject"]["SubObject"]["ObjectsMethod"][ObjectsMethodsVariable"](args..);
... is technically reliable because the compiler avoids dot notation but at runtime it will collect a lot of unnecessary data to maintain those types of calls.
If efficiency becomes an issue..
Use:
package packages {
import flash.*.*:
class This implements ISpecialInterface {
// Data Objects and Function Model
// for This Class
}
package packages {
import...
class ISpecialInterface extends IEventDispatcher
Are static classes pretty much always frowned upon, or is there ever a good time to use them?
For example, would it make sense to implement something ubiquitous in your application like security in a static class? You could still use property injection on the static class to change out the implementation, and if you were to use something like MEF to inject the implementation then I would think it wouldn't get in the way of your tests.
I use static classes mainly for stateless helper classes and when I want to create extension methods. I try to avoid static classes that have state because as you mention it can get in the way of the tests.
Let's say you decide to add state to a static class. To test the methods of this class that depend on its state you will have to find a way to change this state during the tests. This means that you have to:
Prepare the state before each test.
Clear the state after each test.
This means that the class will need to offer a way (by means of internal methods or internal property setters) to alter its state which can be dangerous. If you want to create immutable classes or classes that encapsulate completely their implementation details then you will not be able to test them easily (if not at all) and your test might break more often from changes to the implementation. Even with MEF it will not be easy to do this.
Of course static class sometimes offer attractive solutions for problems like logging and,as mentioned in your question, security. In these cases I would go for a static class that delegates all calls to a private readonly field. This way the class of this field can be unit tested normally. You can then test the static class in your integration tests.
By the way have a look at .NET's design guidelines for static classes. It doesn't include anything relevant to your question but it includes valuable advice.
I'm testing some code that uses StructureMap for Inversion of Control and problems have come up when I use different concrete classes for the same interface.
For example:
[Test]
public void Test1()
{
ObjectFactory.Inject<IFoo>(new TestFoo());
...
}
[Test]
public void Test2()
{
ObjectFactory.Initialize(
x => x.ForRequestedType<IFoo>().TheDefaultIsConcreteType<RealFoo>()
);
// ObjectFactory.Inject<IFoo>(new RealFoo()) doesn't work either.
...
}
Test2 works fine if it runs by itself, using a RealFoo. But if Test1 runs first, Test2 ends up using a TestFoo instead of RealFoo. Aren't NUnit tests supposed to be isolated? How can I reset StructureMap?
Oddly enough, Test2 fails if I don't include the Initialize expression. But if I do include it, it gets ignored...
If you must use ObjectFactory in your tests, in your SetUp or TearDown, make a call to ObjectFactory.ResetAll().
Even better, try to migrate your code away from depending on ObjectFactory. Any class that needs to pull stuff out of the container (other than the startup method) can take in an IContainer, which will automatically be populated by StructureMap (assuming the class itself is retrieved from the container). You can reference the IContainer wrapped by ObjectFactory through its Container property. You can also avoid using ObjectFactory completely and just create an instance of a Container that you manage yourself (it can be configured in the same way as ObjectFactory).
Yes, NUnit tests are supposed to be isolated and it is your responsibility to make sure they are isolated. The solution would be to reset ObjectFactory in the TearDown method of your test fixture. You can use ObjectFactory.EjectAllInstancesOf() for example.
Of course it doesn't reset between tests. ObjectFactory is a static wrapper around an InstanceManager; it is static through an AppDomain and as tests run in the same AppDomain this is why it is not reset. You need to TearDown the ObjectFactory between tests or configure a new Container for each test (i.e., get away from using the static ObjectFactory).
Incidentally, this is the main reason for avoiding global state and singletons: they are not friendly to testing.
From the Google guide to Writing Testable Code:
Global State: Global state is bad from theoretical, maintainability, and understandability point of view, but is tolerable at run-time as long as you have one instance of your application. However, each test is a small instantiation of your application in contrast to one instance of application in production. The global state persists from one test to the next and creates mass confusion. Tests run in isolation but not together. Worse yet, tests fail together but problems can not be reproduced in isolation. Order of the tests matters. The APIs are not clear about the order of initialization and object instantiation, and so on. I hope that by now most developers agree that global state should be treated like GOTO.