I have an adapter class for Linq-to-Sql:
public interface IAdapter : IDisposable
{
Table<Data.User> Activities { get; }
}
Data.User is an object defined by Linq-to-Sql pointing to the User table in persistence.
The implementation for this is as follows:
public class Adapter : IAdapter
{
private readonly SecretDataContext _context = new SecretDataContext();
public void Dispose()
{
_context.Dispose();
}
public Table<Data.User> Users
{
get { return _context.Users; }
}
}
This makes mocking the persistence layer easy in unit testing, as I can just return whatever collection of data I want for Users (Rhino.Mocks):
Expect.Call(_adapter.Users).Return(users);
The problem is that I cannot create the object 'users' since the constructors are not accessible and the class Table is sealed. One option I tried is to just make IAdapter return IEnumerable or IQueryable, but the problem there is that I then do not have access to the methods ITable provides (e.g. InsertOnSubmit()). Is there a way I can create the fake Table in the unit test scenario so that I may be a happy TDD developer?
My current solution is to wrap the functionality I want from Table into a TableWrapper class:
public interface ITableWrapper<TEntity>
where TEntity : class
{
IEnumerable<TEntity> Collection { get; }
void InsertOnSubmit(TEntity entity);
}
And here's the implementation:
public class TableWrapper<TEntity> : ITableWrapper<TEntity>
where TEntity : class
{
private readonly Table<TEntity> _table;
public TableWrapper(Table<TEntity> table)
{
_table = table;
}
public IEnumerable<TEntity> Collection
{
get { return _table; }
}
public void InsertOnSubmit(TEntity entity)
{
_table.InsertOnSubmit(entity);
}
}
So now I can easily mock data from Collection, as well as keeping the functionality of InsertOnSubmit (any other functions that I need down the road can be added later on).
I have had success using the Data Access Layer to produce domain object collections and then using linq to objects.
The object under test then only relates to List, which is fairly easy to unit test.
I don't like when the logic entities should have Data Access Layer dependencies. They should stop at the service layer, if even there. I usually go for the model where the service layer invokes a data access object to get a List, passes that list into whichever logic object that needs it (if necessary uses linq-to-objects to filter out the relevant data and injects it into eiter a flat list, dictionary or an object model).
The business objects become very testable, even though they don't benefit from the richness of the inferred data model.
Related
Consider the following code (in C# but it could be any other language):
public interface IObjectCopier
{
void Copy<T>(T source, T target);
}
public class Model
{
public string Name { get; set; }
}
public class ViewModel
{
private readonly IObjectCopier _objectCopier;
public ViewModel(IObjectCopier objectCopier)
{
_objectCopier = objectCopier;
}
public Model ViewBindData { get; set; }
public void Load(Model model)
{
_objectCopier.Copy(model, ViewBindData);
}
}
How do I construct a unit test for the Load method? If I mock IObjectCopier then I need to supply a mock implementation of the Copy method. In this example it is trivial but in a real world scenario Model can be large with sub models and the mocking exercise feel like it is just copying what the IObjectCopier implementation does.
The problem is simplified if I could change the Copy method to the following:
T Copy<T>(T source);
As in this case the mock setup is drastically simplified. The problem is that there are view bindings to the Model object and I cannot simply destroy and re-create the object.
Is there an elegant way to get around this problem?
If you're using mocks, then the only thing you care about is that the copier is invoked with the 2 parameters.
So in some sort of pseudo code
test "populates model from view data" {
objectCopiermock = mock(IObjectCopier)
model = new Model() //create empty or use a TestDataBuilder
viewBindData = new viewBindData() //create empty or use a TestDataBuilder
viewModel = new ViewModel(objectCopiermock)
viewModel.viewBindData(viewBindData)
viewModel.Load(model)
verifyMock(objectCopiermock).copy(model, viewBindData)
}
The important thing with mocks is to verify the interactions, and not the values inside model or viewBindData.
If this is confused, don't panic! (tm) - and I would suggest you to read a bit about the difference between the London and Chicaco/Detroit schools of TDD
I am a Dagger newbie.
TL;DR:
If an Android Service has any fields injected into it using Dagger, then in order to actually perform the injection, I need to have an instance of that Service.
In Robolectric tests, this corresponds to MyService service = Robolectric.buildService(MyService.class).get(). And then, objectGraph.inject(service);
However, rest of the code that actually starts MyService still uses context.startService(context, MyService.class);.
Question: What is the idiomatic way in Dagger to address this mismatch?
Let's say I have a Service as follows:
public class MyService {
#Inject Parser parser;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String data = intent.getStringExtra("data_to_be_parsed");
parser.parse(data);
}
}
Elsewhere in my code, I have an ApiClient class that does this:
public class ApiClient{
public static void parseInBackground(Context context, String data){
//This service does not have its fields injected
context.startService(new Intent(context, MyService.class).putExtra("data_to_be_parsed", data));
}
}
That parseInBackground method will be called from an Activity in response to user interaction.
Now, I'm following TDD and hence, I haven't yet written the Application Module for this. Here's the test module:
#Module(injects = MyService.class)
public class TestModule {
#Provides #Singleton Parser provideParser(){
return new MockParser();
}
}
And finally, the test case:
#RunWith(Robolectric.class)
public class ApiTest {
#Test
public void parseInBackground_ParsesCorrectly(){
//This service has its fields injected
MyService service = Robolectric.buildService(MyService.class).get();
ObjectGraph.create(new TestModule()).inject(service);
ApiClient.parseInBackground(Robolectric.application, "<user><name>droid</name></user>");
//Asserts here
}
}
As you can see, in the test, I retrieve an instance of the service and then inject the MockParser into it. However, the ApiClient class directly starts the service using an Intent. I don't have a chance to perform the injection.
I am aware that I can have MyService perform an injection on itself:
public void onCreate(){
ObjectGraph.create(new TestModule()).inject(this);
}
But then, I am hardcoding the TestModule here.
Is there an existing idiom in Dagger to set up dependencies for such situations?
It's the wrong way to hardcode your modules either in tests or in services. Better approach is to perform creation via your custom Application object which in turn will hold singleton ObjectGraph object. For example:
// in MyService class
#Override public void onCreate() {
super.onCreate();
MyApp.from(context).inject(this);
}
// in MyApp class
public static MyApp from(Context context) {
return (MyApp) context.getApplicationContext();
}
//...
private ObjectGraph objectGraph;
#Override public void onCreate() {
// Perform Injection
objectGraph = ObjectGraph.create(getModules());
objectGraph.inject(this);
}
public void inject(Object object) {
objectGraph.inject(object);
}
protected Object[] getModules() {
// return concrete modules based on build type or any other conditions.
}
Alternatively, you can refactor last method out into separate class and make different implementations for different flavors or build types. Also you may want to set overrides=true in your TestModule's annotation.
I would like to write a non-regression test to validate that transient components are well released. Some are created by a direct injection in ctor, other by typed factories.
I thought that I could do this way:
// Given
var rootComponent = container.Resolve<IRootComponent>();
var c1 = rootComponent.C1;
var c2 = c1.C2;
etc.
Assert.True(Container.Kernel.ReleasePolicy.HasTrack(c1));
Assert.True(Container.Kernel.ReleasePolicy.HasTrack(c2));
// When
c1.Close();
// Then
Assert.False(Container.Kernel.ReleasePolicy.HasTrack(c1));
Assert.False(Container.Kernel.ReleasePolicy.HasTrack(c2));
HasTrack() always returns false, although if I look at the container in debug mode, I can see my components well tracked. Why is that? Do you have any suggestion for such a test?
Thx for your help
The reason that your components are not tracked is that the component and it's dependencies have no decomissioning requirements. In this case there is no reason for windsor to track them.
When using windsor in general you should only resolve on your container once to obtain your top level component. All other component are either injected or created by a factory. There is no need to worry about the live time of injected components. The container will handle it for you.
For transient components that you create with a factory you should be aware that they will never live (be tracked) longer then the factory it self. So if you don't mind that your components live at long as your factory there is no need to release them (using a destroy method on a factory).
For component that I want to make sure that I release them, I generally I create unit test for which I stub out the factory. That way it is easy to test that destroy is called.
I think with the approach that you are taking you are not just testing your code but also the container. IMHO windsor is already well tested, and test should focus on your own code.
Good luck,
Marwijn.
Two years too late, but here's a test.
public class DependsOnSomethingDisposable
{
private readonly SomethingDisposable _disposable;
public Boolean SomethingDisposableIsDisposed { get { return _disposable.Disposed; } }
public DependsOnSomethingDisposable(SomethingDisposable disposable)
{
_disposable = disposable;
}
}
public class SomethingDisposable : IDisposable
{
public Boolean Disposed { get; private set; }
public void Dispose()
{
Disposed = true;
}
}
[TestClass]
public class WindsorLifestyleTests
{
private IWindsorContainer _container;
[TestInitialize]
public void Setup()
{
_container = new WindsorContainer();
}
[TestCleanup]
public void Cleanup()
{
_container.Dispose();
}
[TestMethod]
public void TransientDependencyIsDisposed()
{
_container.Register(
Component.For<DependsOnSomethingDisposable>().LifestyleTransient(),
Component.For<SomethingDisposable>().LifestyleTransient()
);
var resolved = _container.Resolve<DependsOnSomethingDisposable>();
_container.Release(resolved);
Assert.IsTrue(resolved.SomethingDisposableIsDisposed);
}
[TestMethod]
public void NonTransientDependencyIsNotDisposed()
{
_container.Register(
Component.For<DependsOnSomethingDisposable>().LifestyleTransient(),
Component.For<SomethingDisposable>().LifestyleSingleton()
);
var resolved = _container.Resolve<DependsOnSomethingDisposable>();
_container.Release(resolved);
Assert.IsFalse(resolved.SomethingDisposableIsDisposed);
}
}
I'm trying to start using Unit Testing on my current project in Visual Studio 2010. My class structure, however, contains a number of interface and abstract class inheritance relationships.
If two classes are derived from the same abstract class, or interface I'd like to be able to share the testing code between them. I'm not sure how to do this exactly. I'm thinking I create a test class for each interface I want to test, but I'm not sure the correct way to feed my concrete classes into the applicable unit tests.
Update
OK here's an example. Say I have an interface IEmployee , which is implemented by an abstract class Employee, which is then inherited by the two concrete classes Worker and Employee. (Code show below)
Now say I want to create tests that apply to all IEmployees or Employees. Or alternatively create specific tests for specific types of Employees. For example I may want to assert that setting IEmployee.Number to a number less then zero for any implementation of IEmployee throws an exception. I'd prefer to write the tests from the perspective of any IEmployee and then be able to use the tests on any implementation of IEmployee.
Here's another example. I may also want to assert that setting the vacation time for any employee to a value less then zero throws and error. Yet I may also want to have different tests that apply to a specific concrete version of Employee. Say I want to test that Worker throws an exception if they are provided more then 14 days vacation, but a manager can be provided up to 36.
public interface IEmployee
{
string Name {get; set;}
int Number {get; set;}
}
public abstract class Employee:IEmploee
{
string Name {get; set;}
int Number {get;set;}
public abstract int VacationTime(get; set;)
}
public abstract class Worker:IEmployee
{
private int v;
private int vTime;
public abstract int VacationTime
{
get
{
return VTime;
}
set
{
if(value>36) throw new ArgumentException("Exceeded allowed vaction");
if(value<0)throw new ArgumentException("Vacation time must be >0");
vTime= value;
}
}
public void DoSomWork()
{
//Work
}
}
public abstract class Manager:IEmployee
{
public abstract int VacationTime
{
get
{
return VTime;
}
set
{
if(value>14) throw new ArgumentException("Exceeded allowed vaction");
if(value<0)throw new ArgumentException("Vacation time must be >0");
vTime= value;
}
}
public void DoSomeManaging()
{
//manage
}
}
So I guess what I'm looking for is a work flow that will allow me to nest unit tests. So for example when I test the Manager class I want to first test that it passes the Employee and IEmployee tests, and then test specific members such as DoSomeManaging().
I guess I know what you mean. I had the same issue.
My solution was to create a hierarchy also for testing. I'll use the same example you show.
First, have an abstract test class for the base IEmployee.
It has two main things:
i. All the test methods you want.
ii. An abstract method that returns the desired instance of the IEmployee.
[TestClass()]
public abstract class IEmployeeTests
{
protected abstract GetIEmployeeInstance();
[TestMethod()]
public void TestMethod1()
{
IEmployee target = GetIEmployeeInstance();
// do your IEmployee test here
}
}
Second, you have a test class for each implementation of IEmployee, implementing the abstract method and providing appropriate instances of IEmployee.
[TestClass()]
public class WorkerTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new Worker();
}
}
[TestClass()]
public class ManagerTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new Manager();
}
}
You can see everything works as expected and VS gives you the expected test methods for each WorkerTests and ManagerTests classes in the TestView window.
You can run them and have the test results for each implementation of the IEmployee interface, having to create the tests only in the base IEmployeeTests class.
You can always add specific test for the derived WorkerTests and ManagerTests classes.
The question would be now, what about classes that implement multiple interfaces, let's say EmployedProgrammer?
public EmployedProgrammer : IEmployee, IProgrammer
{
}
We don't have multiple inheritance in C#, so this is not an option:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests, IProgrammerTests
{
// this doesn't compile as IEmployeeTests, IProgrammerTests are classes, not interfaces
}
For this scenario, a solution is to have the following test classes:
[TestClass()]
public EmployedProgrammerIEmployeeTests : IEmployeeTests
{
protected override GetIEmployeeInstance()
{
return new EmployedProgrammer();
}
}
[TestClass()]
public EmployedProgrammerIProgrammerTests : IProgrammerTests
{
protected override GetIProgrammerInstance()
{
return new EmployedProgrammer();
}
}
with
[TestClass()]
public abstract class IProgrammerTests
{
protected abstract GetIProgrammerInstance();
[TestMethod()]
public void TestMethod1()
{
IProgrammer target = GetIProgrammerInstance();
// do your IProgrammerTest test here
}
}
I'm using this with good results.
Hope it helps.
Regards,
Jose
What I think you want to do is create unit tests for methods in abstract classes.
I'm not sure it makes sense to want to test a protected method on an abstract class, but if you insist simply extend the class in a class used exclusively for unittesting. That way you can expose the protected methods on the abstract class you want to test through public methods on the extending class that simply call through to the method on the abstract class.
If you have methods in abstract classes that you want unittested, I suggest refactoring them into separate classes and simply expose them as public methods and put those under test. Try looking at your inheritance tree from a 'test-first' perspective and I'm pretty sure you'll come up with that solution (or a similar one) as well.
It seems that you have described "composite unit testing" which is not supported by Visual Studio 2010 unit tests. Such things can be done in MbUnit according to this article. It is possible to create abstract tests in Visual Studio 2010 which is probably not exactly what you want. Here is description how to implement abstract tests in VS (Inheritance Example section).
Use microsoft moles for better testing. so you can mock the abstract base class / static methods etc easily. Please refer the following post for more info
detouring-abstract-base-classes-using-moles
BenzCar benzCar = new BenzCar();
new MCar(benzCar)
{
Drive= () => "Testing"
}.InstanceBehavior = MoleBehaviors.Fallthrough;
var hello = child.Drive();
Assert.AreEqual("Benz Car driving. Testing", hello);
The desire to run the same test against multiple classes usually means you have an opportunity to extract the behavior you want to test into a single class (whether it's the base class or an entirely new class you compose into your existing classes).
Consider your example: instead of implementing vacation limits in Worker and Manager, add a new member variable to Employee, 'MaximumVacationDays', implement the limit in the employee class' setter, and check the limit there:
abstract class Employee {
private int maximumVacationDays;
protected Employee(int maximumVacationDays) {
this.maximumVacationDays = maximumVacationDays
}
public int VacationDays {
set {
if (value > maximumVacationDays)
throw new ArgumentException("Exceeded maximum vacation");
}
}
}
class Worker: Employee {
public Worker(): Employee(14) {}
}
class Manager: Employee {
public Manager(): Employee(36) {}
}
Now you have only one method to test and less code to maintain.
I am trying to unit test an action filter I wrote. I want to mock the HttpClientCertificate but when I use MOQ I get exception. HttpClientCertificate doesnt have a public default constructor.
code:
//Stub HttpClientCertificate </br>
var certMock = new Mock<HttpClientCertificate>();
HttpClientCertificate clientCertificate = certMock.Object;
requestMock.Setup(b => b.ClientCertificate).Returns(clientCertificate);
certMock.Setup(b => b.Certificate).Returns(new Byte[] { });
This is the most awkward case of creating unit testable systems in .NET. I invariable end up adding a layer of abstraction over the component that I can't mock. Normally this is required for classes with inaccessible constructors (like this case), non-virtual methods or extension methods.
Here is the pattern I use (which I think is Adapter pattern) and is similar to what MVC team has done with all the RequestBase/ResponseBase classes to make them unit testable.
//Here is the original HttpClientCertificate class
//Not actual class, rather generated from metadata in Visual Studio
public class HttpClientCertificate : NameValueCollection {
public byte[] BinaryIssuer { get; }
public int CertEncoding { get; }
//other methods
//...
}
public class HttpClientCertificateBase {
private HttpClientCertificate m_cert;
public HttpClientCertificateBase(HttpClientCertificate cert) {
m_cert = cert;
}
public virtual byte[] BinaryIssuer { get{return m_cert.BinaryIssuer;} }
public virtual int CertEncoding { get{return m_cert.CertEncoding;} }
//other methods
//...
}
public class TestClass {
[TestMethod]
public void Test() {
//we can pass null as constructor argument, since the mocked class will never use it and mock methods will be called instead
var certMock = new Mock<HttpClientCertificate>(null);
certMock.Setup(cert=>cert.BinaryIssuer).Returns(new byte[1]);
}
}
In your code that uses HttpClientCertificate you instead use HttpClientCertificateBase, which you can instantiate like this - new HttpClientCertificateBase(httpClientCertificateInstance). This way you are creating a test surface for you to plug in mock objects.
The issue is that you need to specify constructor parameters when creating the mock of the HttpClientCertificate.
var certMock = new Mock<HttpClientCertificate>(ctorArgument);
The bad news is that the ctor for HttpClientCertificate is internal and takes in an HttpContext, so it probably won't work.
Unless you want to write more code to make the class "Testable" I suggest you use Typemock Isolator, Unless specified otherwise it looks for the first c'tor available - public, internal or private and fake (mocks) it's parameters so you won't have to.
Creating the fake object is as simple as:
var fakeHttpClientCertificate = Isolate.Fake.Instance<HttpClientCertificate>();
Another alternative is to use the free Microsoft Moles framework. It will allow you to replace any .NET method with your own delegate. Check out the link as it gives an example that is pretty easy to understand. I think you'll find it much nicer than adding layers of indirection to get HttpClientCertificate into a testable state.