My projects all use StructureMap as a container/IoC. I leverage this in things like repository patterns. In my unit test project, I've implemented test repositories when it makes sense. In order for structure map to know what concrete implementation to use, I need to initialize the container and run registration of types. I'm looking for a place to call my IoC.Initialize() in a unit test project. Outside of unit test, for example, in a web project, I can initialize my IoC container/registration from the Global.asax. I'm looking for a Unit Test equivalent of a Global.asax (e.g. static void main, a way to wire into the main start up event entry point of Unit tests). I've got around this by using a base class for all my tests, and initializing in there, so any test that is run ends up initializing the IoC container if it's not already initialize... but it's very hack-ish IMHO, so I'm looking for a cleaner way.
Any suggestions?
UPDATE/ANSWER
The following is the solution I implemented per Matthew's response.
<TestClass()>
Public Module Main
Public Property TestContext As TestContext
<AssemblyInitialize()>
Public Sub Initialize(_TestContext As TestContext)
TestContext = _TestContext
IoC.Initialize()
End Sub
End Module
You're probably looking for the AssemblyInitializeAttribute. You can decorate a method with this in a class in your assembly and it will be run once before any tests in that assembly get run.
Related
I want to test my class EventTextsDB that is a singleton, using MSTest in .NET 6.
I first thought about using AppDomain, but they basically were removed in .NET 5+ (https://learn.microsoft.com/en-us/dotnet/core/porting/net-framework-tech-unavailable#application-domains)
Then I found Unit test singletons, but by calling the private constructor via reflection I still cannot test the static Create() and static Delete() methods in the class, because they set the static EventTextsDB Instance property.
I could use ordered unit tests, but this would require a lot of work because I would have to order all tests that used this class. Not many tests use or test this class yet, but many do with a similar class LanguageDB, at which I want to apply the same solution that I am looking for.
I have read somewhere on stackoverflow or MSDN, that each test assembly runs isolated (in different AppDomain, if they still exist?), but I don't want to create 10 new test assemblies just for 10 tests of this class.
How can I test my singleton class?
public bool A (UserRequest foo)
{
ClientRequest boo = B(foo); //Mapping local model to client model
C(boo);
return result;
}
I want to write an unit test for method A to test method B but I don't want my unit test to call method C. Method C is a private method but it makes calls to a third party client. I am unable to setup method C in my Unit Test since the type "ClientRequest" doesn't have a reference in the test case assembly. How can this be implemented without adding a reference of the client dll to my test assembly as well. How to skip calling method C ?
C is a private method
Things are private for a reason. They are implementation details to which consuming code shouldn't be coupled. And unit tests are consuming code.
it makes calls to a third party client
Therein lies the problem with your unit tests. Don't try to break apart the class being tested, digging into its internals and ultimately modifying what it's doing and as a result invalidating the tests in the first place.
Instead, isolate and mock the dependency. Somewhere in C() this class has an external dependency. Instead of obscuring that dependency deep within the class, wrap it in an interface/implementation and provide that implementation to the class. (This is called Dependency Injection. There are frameworks which provide rich functionality around the concept, but the concept itself can be achieved manually for simple cases as well.)
So when application code uses this class, instances are provided with an implementation of the dependency which calls the external service. And when unit tests use this class, instances are provided with a mock implementation that pretends to call the external service.
Then your tests can include mocking the results of that service as well, triggering controlled failure responses to test how the class handles them.
Basic layout is currently a simple app. Nothing fancy, I've got Views in the App.Views namespace and my ViewModels in the App.ViewModels namespace. The ViewModels are autowired to the Views through the XAML directive:
xmlns:prismMvvm="using:Prism.Windows.Mvvm"
prismMvvm:ViewModelLocator.AutoWireViewModel="True"
So, basically, this works. Then I wanted to leverage Unity's IoC / DependencyInjection for some unit tests.
The usual way would be to simply add a Windows 10 Unit Test App to the existing app and reference the latter in the Unit Test App.
This will crash upon executing the unit tests because it seems that you may not derive the App class from anything other but Application.
I.e. this works:
public sealed partial class App : Application
This does not:
public sealed partial class App : PrismUnityApplication
It's probably also not Prism's fault and something Microsoft has to fix on their end.
Now, the proposed workaround is to simply put whatever you want to unit test into a class library and reference this library from the unit test app. This works for unit testing. It also works for the Models.
My naive approach does not work, however, for the ViewModels. The ViewModel classes are still found under the App.ViewModels namespace, as before, just that they're now in a Class Library. I can access them programmatically in the main app just fine. But upon running the program, the AutoWiring silently fails without an error.
Even when I do something like this, it still does not work:
ViewModelLocationProvider.Register(typeof(MainPage).ToString(), () => new ViewModels.MainPageViewModel());
I'm not that experienced with the technologies involved yet so without an actual error I'm a bit at a loss.
edit: Just to add to the mystery - this code does work, regardless of whether the ViewModel resides in the main app or the class library:
var x = Container.Resolve(typeof(ExamplePageViewModel)) as ExamplePageViewModel;
You are correct, this is a limitation of UWP application testability in general. The testability of UWP apps is imperfect right now. In order to fix the first issue, you need to add the BindableAttribute to your application class:
[Bindable]
sealed partial class App : PrismUnityApplication
{
}
As far as pulling your Views/ViewModels out into separate assemblies, this issue is due to how UWP handles loading types form separate assemblies. None the less, this shouldn't stop you from testing your ViewModels. You can use a regular class library to test your ViewModel logic. You will mock your dependencies. You shouldn't be creating instances of your Views to test your ViewModels. So the ViewModelLocator becomes a non-issue.
We got the same issue as you, test silently failing.
when we looked at the Test output window we saw this:
App activation failed.
Failed to initialize client proxy: could not connect to test process.
Inside our [UnitTestApp], which inherits [PrismUnityApplication], we override [ConfigureContainer] method, and setup mocks on the container, instead of setting up real classes, i.e.
UnitTestApp.Current.Container.RegisterInstance(myMock.Object, new ContainerControlledLifetimeManager());
You may also have the Container setup in each test class' constructor
This way we got our test running without a silent failure.
It seemed that the silent failure was due to the container of the actual App class being called in the context of the UnitTestApp class - but I cannot confirm 100%
In an MVC4 C# website, we are using Unit Testing to test our code. What we are currently doing is creating a mock database, then testing each layer:
Test the Database - connecting, initializing, load, etc.
Test the code accessing the database
Test the view layer
I want these three categories to be run in order and only if the previous one passed. Is this the right way to go about it? The old way we were doing it was using a Dependency Injection framework was a weird approach to mock testing. We actually created a mock class for each data accessor, which sucks because we have to re implement the logic of each method, and it didn't really add any value because if we made a mistake with the logic the first time, we'll make it a second.
I want these three categories to be run in order and only if the
previous one passed. Is this the right way to go about it?
No. You should be test everything in isolation and because of that any failing data access code should be completely unrelated to the view. So the view unit tests should fail for a completely different reason and because of that you should always run all tests.
In general, tests should run in isolation, and should not depend on any other tests. It seems to me that the view layer still depends on the data access code, but that you only abstracted the layer below. In that case, from the view's perspective, you are mocking an indirect dependency, which makes your unit tests more complex than strictly needed.
The old way we were doing it was using a Dependency Injection
framework was a weird approach to mock testing
I'm not sure if I get this, but it seems as if you were using the DI container inside your unit tests. This is a absolute no-no. Don't clutter your tests with any DI framework. And there's no need to. Just design your classes around the dependency injection principle (expose all dependencies as constructor arguments) and in your test you just manually new up the class under test with fake dependencies -or- when this leads to repetitive code, create a factory method in your test class that creates a new instance of the class under test.
We actually created a mock class for each data accessor, which sucks
I'm not sure, but it sounds as if there's something wrong with your design here. You would normally have a IRepository<T> interface for which you would have multiple implementations, such as a UserRepository : IRepository<User>, and OrderRepository : IRepository<Order>. In your test suite, you will have one generic FakeRespository<T> or InMemoryRepository<T> and you're done. No need to mock many classes here.
Here are two great books you should definitely read:
The Art of Unit Testing
Dependency Injection in .NET
Those books will change your life. And since you'll be reading anyway, do read this book as well (not related to your question, but code be a life changer as well).
After all what I have read about Dependency Injection and IoC I have decided to try to use Windsor Container within our application (it's a 50K LOC multi-layer web app, so I hope it's not an overkill there). I have used a simple static class for wrapping the container and I initialize it when starting the app, which works quite fine for now.
My question is about unit testing. I know that DI is going to make my life much easier there by giving me the possibility of injecting stub / mock implementations of class collaborators to the class under test. I have already written a couple of tests using this technique and it seems to make sense for me. What I am not sure about is whether I should be using IoC (in this case Windsor Castle) also in unit tests (probably somehow configure it to return stubs / mocks for my special cases) or is it better to wire-up all the dependencies manually in the tests. What do you think and what practice has worked for you ?
You don't need DI container in unit tests because dependencies are provided through mock objects generated with frameworks such as Rhino Mocks or Moq. So for example when you are testing a class that has a dependency on some interface this dependency is usually provided through constructor injection.
public class SomeClassToTest
{
private readonly ISomeDependentObject _dep;
public SomeClassToTest(ISomeDependentObject dep)
{
_dep = dep;
}
public int SomeMethodToTest()
{
return _dep.Method1() + _dep.Method2();
}
}
In your application you will use a DI framework to pass some real implementation of ISomeDependentObject in the constructor which could itself have dependencies on other objects while in a unit test you create a mock object because you only want to test this class in isolation. Example with Rhino Mocks:
[TestMethod]
public void SomeClassToTest_SomeMethodToTest()
{
// arrange
var depStub = MockRepository.CreateStub<ISomeDependentObject>();
var sut = new SomeClassToTest(depStub);
depStub.Stub(x => x.Method1()).Return(1);
depStub.Stub(x => x.Method2()).Return(2);
// act
var actual = sut.SomeMethodToTest();
// assert
Assert.AreEqual(3, actual);
}
I'm working on an ASP.NET MVC project with about 400 unit tests. I am using Ninject for dependency injection and MBUnit for testing.
Ninject is not really necessary for unit testing, but it reduces the amount of code I have to type. I only have to specify once (per project) how my interfaces should be instantiated as opposed to doing this every time I initialize the class being tested.
In order to save time on writing new tests, I have created test fixture base classes with as much generic setup code as possible. The setup procedures in those classes intialize fake repositories, create some test data and a fake identity for the test user. Unit tests only initialize data that is too specific to go into generic setup procedures.
I am also mocking objects (as opposed to faking) in some tests, but I found that faking data repositories results in less work and more accurate tests.
For example, it would be more difficult to check if the method under test I properly commits all updates to the repository after making them when using a repository mock than when I am using a repository fake.
It was quite a bit of work to set up at the beginning, but really helped me reduce save a lot of time in the long run.
I've just written a very similar style and size app. I wouldn't put any dependency injection in the unit tests because it is not complicated enough to be necessary. You should use a mocking framework to create your mocks (RhinoMocks / Moq).
Also Automocking in Moq or the Auto Mock Container in Rhinomocks will simplify building your mocks further.
Auto mocking allows you to get object
of the type you want to test without
setting up mocks by hand. All
dependencies are mocked automatically
(assuming they are interfaces) and
injected into the type constructor. If
you need to you can set up expected
behavior, but you don't have to.
As Darin has already pointed out, you don't need to use DI if you have mocks. (However, DI has a few other benefits as well, including, first of all, lessening dependencies in your code, which makes your code much easier to maintain and extend in the long run.)
I personally prefer wiring up everything in my unit tests, thus relying as little as possible on external frameworks, config files etc.