xUnit tests are failed with shared static data - c#

I have several unit tests that use some static class, for example:
public static class Utility
{
private static Data data;
public static void Init(Data data)
{
this.data = data;
}
public static void Process()
{
// Some actions that changes this.data (not reference, just inner Values)
}
}
public class Data
{
public List<string> Values { get; set; }
public void Add(string value)
{
Values.Add(value);
}
}
Each unit test initializes Data instance and passes it to Utility:
[Fact]
public void UnitTest1()
{
var data = new Data();
data.Add("val1");
Utility.Init(data);
Utility.Process();
// check changed data instance
}
[Fact]
public void UnitTest2()
{
var data = new Data();
data.Add("another_val1");
data.Add("another_val2");
Utility.Init(data);
Utility.Process();
// check changed data instance
}
If I run each test separately then there is no problem - no failed tests.
But If I run tests sequentially then one of the unit tests is failed because Utility.data contains instance from previous test (for a short time) despite of Utility.Init call.
If I run tests through command line (tests performs very fast) then big part of tests is failed most likely for the same reason. How can I resolve this problem?

Because of the nature of the static utility all the tests are accessing a shared static resource which can have negative effects as already experience. I suggest making the utility class an instance class
public class Utility
{
private Data data;
public Utility(Data data) {
this.data = data;
}
public void Process() {
// Some actions that changes this.data (not reference, just inner Values)
}
}
Which an example test would look like
[Fact]
public void UnitTest1() {
//Arrrange
var data = new Data();
data.Add("val1");
var subject = new Utility(data);
//Act
subject.Process();
//Assert
// check changed data instance
}
I suspect that the initil issue was an XY problem and that the Utility is also being used as a static dependency in production, which is a code smell.
In that case abstract the static utility class
public interface IUtility {
void Process(Data data);
}
and refactor the implementation
public class Utility : IUtility {
public void Process(Data data) {
// Some actions that changes this.data (not reference, just inner Values)
}
}
Which would result in a test looking like
[Fact]
public void UnitTest1() {
//Arrrange
var data = new Data();
data.Add("val1");
var subject = new Utility();
//Act
subject.Process(data);
//Assert
// check changed data instance
}
[Fact]
public void UnitTest2() {
var data = new Data();
data.Add("another_val1");
data.Add("another_val2");
var subject = new Utility();
//Act
subject.Process(data);
//Assert
// check changed data instance
}
The IUtility would be injected into dependent classes as needed, which would make the resulting code more SOLID.

Related

Issue with Unit Testing Model View Presenter

I am creating an application in ASP.NET web form with MVP pattern. I am getting some issues working with TDD. I have created two test, one is working fine but when a second test is executed it throws an error.
Below is my declared View
public interface IAddUpdateView : IView
{
string Type { get; set; }
string PageTitle { set; }
string Details { get; set; }
bool Active { get; set; }
}
Presenter
// BasePresenter is an abstract class contains abstract method with name Initialize()
public class MyPresenter: BasePresenter<IAddUpdateView >
{
private readonly IDatabaseLayer _databaselayer;
public MyPresenter(IAddUpdateView view, IDatabaseLayer databaseLayer) : base(view)
{
_databaselayer = databaseLayer;
}
public override void Initialize()
{ }
public void Initialize(string str)
{
string[] str1=Misc.DecryptURL(str);
View.Type = str1[0].ToString(); // ERROR LINE
if (View.Type.ToLower().Trim() == "add")
{
View.PageTitle = "Add New Task";
}
else if (View.Type.ToLower().Trim() == "edit")
{
}
}
}
Now I am working on creating unit test mocking the Presenter class to test the dependencies using Rhino mocks.
That's my test class with just two test methods. These test methods test when loading a View it calls appropriate Page Type.
When ADD type is called, it get the View.Type as "add" and when Edit type is called, it verifies for the specific object that is loaded.
[TestFixture]
public class MyPresenterTest
{
private IAddUpdateView _view;
private MyPresernter _controller;
[SetUp]
public void SetUp()
{
_view = MockRepository.GenerateMock<IAddUpdateView >();
_controller = new MyPresernter (_view, MockDataLayer());
}
[TearDown]
public void TearDown() { _controller = null; _view = null; }
// TEST 1
[Test]
public void When_Loading_for_Add_View_Panel_Return_Type_Add()
{
// Arrange
_view.Stub(x => x.Type).PropertyBehavior();
//Act
_controller.Initialize(GetURLWithAddValue());
// GetURLWithAddValue: This method get the URL with querystring contains value as "add"
//Assert
Assert.AreEqual("add",_view.Type);
}
TEST 2
// When this test method is run, It has the Type="edit", but in my
presenter View.Type (see LINE ERROR), my Type is null even I
assigned the values.
[Test]
public void When_Loading_for_Edit_View_Panel_Load_Correct_Object()
{
// Arrange
_view.Stub(x =>x.TaskDetails).PropertyBehavior();
//Act
Task o=new Task(){ TaskId=6, TASK_NAME="Task 6"};
_controller.Initialize(GetURLWithEditValue(o));
//Assert
Assert.AreEqual(o.TASK_NAME, _view.TaskDetails);
}
private static IDatabaseLayer MockDataLayer()
{
IDatabaseLayer obj = MockRepository.GenerateMock<IDatabaseLayer>();
MockTaskDataLayer a = new MockTaskDataLayer();
obj.Stub(x => x.GetList());
return obj;
}
}
Can someone guide me why Test 1 get passed and when Test 2 is executed, after assigning a value in View.Type (see LINE ERROR in MyPresenter class) it's still null??
Thanks,

Automatically calling an init function whenever an object is used for the 1st time

I have an object that only initializes itself with barebones data when constructed (fast), and loads itself for real (slow) when first accessed. The idea is that I'm creating a lot of these barebones objects at startup and hash them into a map, then fully load each object whenever it is individually accessed for the first time. The problem is that I cannot guarantee how clients will interact with this object, there are multiple public methods that might be invoked.
Is there a good pattern to support this kind of situation? The obvious (and my current) solution is to track state with an internal bool, check against that bool in every function that might be invoked, and load that way. But that requires code duplication of that behavior across all public functions, and is vulnerable to errors.
I can imagine a single point-of-entry method that then dishes out behaviors based on a client request type etc., but before I go consider going down that road I want to see if there's a commonly accepted approach/pattern that I might not be aware of. I'm doing this in C#, but any insight is appreciated.
If I understood what you want to achieve, you are looking for the Proxy Design Pattern, more specifically, a virtual Proxy.
Refer to http://www.dofactory.com/net/proxy-design-pattern
A small example would be something like:
public abstract class IObjectProvider
{
public abstract IObjectProvider Object{get;}
public abstract void doStuff();
}
public class RealObject : IObjectProvider
{
public RealObject()
{
//Do very complicated and time taking stuff;
}
public override IObjectProvider Object
{
get { return this; }
}
public override void doStuff()
{
//do this stuff that these objects normally do
}
}
public class ObjectProxy : IObjectProvider
{
private IObjectProvider objectInstance = null;
public override IObjectProvider Object
{
get
{
if (objectInstance == null)
objectInstance = new RealObject();
return objectInstance;
}
}
public override void doStuff()
{
if(objectInstance!=null)
objectInstance.doStuff();
}
}
public class SkeletonClass
{
public IObjectProvider Proxy1 = new ObjectProxy();
public IObjectProvider Proxy2 = new ObjectProxy();
}
static void Main(String[] args)
{
//Objects Not Loaded
SkeletonClass skeleton = new SkeletonClass();
//Proxy1 loads object1 on demand
skeleton.Proxy1.Object.doStuff();
//Proxy2 not loaded object2 until someone needs it
}
Here's an example of dynamic proxy approach.
using System;
using System.Diagnostics;
using Castle.DynamicProxy; //Remember to include a reference, too. It's nugettable package is Castle.Core
namespace ConsoleApp
{
public class ActualClass
{
//Have static instances of two below for performance
private static ProxyGenerator pg = new ProxyGenerator();
private static ActualClassInterceptor interceptor = new ActualClassInterceptor();
//This is how we get ActualClass items that are wrapped in the Dynamic Proxy
public static ActualClass getActualClassInstance()
{
ActualClass instance = new ActualClass();
return pg.CreateClassProxyWithTarget<ActualClass>(instance, interceptor);
}
//Tracking whether init has been called
private bool initialized = false;
//Will be used as evidence of true initialization, i.e. no longer null
private int? someValue = null;
public void Initialize()
{
if (!initialized)
{
//do some initialization here.
someValue = -1; //Will only get set to non-null if we've run this line.
initialized = true;
}
}
//Any methods you want to intercept need to be virtual!
public virtual int replaceValue(int value)
{
//below will blow up, if someValue has not been set to -1 via Initialize();
int oldValue = someValue.Value;
someValue = value;
return oldValue;
}
//block off constructor from public to enforce use of getActualClassInstance
protected ActualClass() { }
}
public class ActualClassInterceptor : ActualClass, IInterceptor
{
public void Intercept(IInvocation invocation)
{
//Call initialize before proceeding to call the intercepted method
//Worth noting that this is the only place we actually call Initialize()
((ActualClass)invocation.InvocationTarget).Initialize();
invocation.Proceed();
}
}
class Program
{
static void Main(string[] args)
{
ActualClass instance1 = ActualClass.getActualClassInstance();
ActualClass instance2 = ActualClass.getActualClassInstance();
int x1 = instance1.replaceValue(41);
int x2 = instance2.replaceValue(42);
int y1 = instance1.replaceValue(82);
Debug.Assert(y1 == 41);
int y2 = instance2.replaceValue(84);
Debug.Assert(y2 == 42);
var read = Console.ReadKey();
}
}
}

How to configure Moq to make use of generic action<T>

I have a facade class that uses a WCF client proxy. To prevent issues with the WCF proxy client with IDispose (bug in WCF, still not fixed by MS), I have created a generic proxy service to do the basic plumbing for calling the WCF service.
I want to unit test the facade with Moq, and I have an issue how to get into specific call within a unit test using Moq. The unit test wants to verify that the call to the process manager was done just once, but the code does not flow within the 'Use' method....
(edit)
For completeness here is the part that fixed the issue:
public AuthenticationFacade CreateSut()
{
ProcessManager = new Mock<IProcessManager>().Object;
SessionWrapper = new Mock<ISessionWrapper>().Object;
AuthenticationClientProxy = new Mock<Action<IAuthentication>>().Object;
var authenticationProxyServiceMock = new Mock<IProxyService<IAuthentication>>();
Mock<IAuthentication> mockAuthentication = new Mock<IAuthentication>();
authenticationProxyServiceMock.Setup(aps => aps.Use(It.IsAny<Action<IAuthentication>>()))
.Callback<Action<IAuthentication>>(ac => ac(mockAuthentication.Object));
AuthenticationProxyService = authenticationProxyServiceMock.Object;
return new AuthenticationFacade(ProcessManager, SessionWrapper, AuthenticationProxyService);
}
(reference code)
Code part 1:
using System;
namespace Progis.Kim
{
public interface IProxyService<T>
{
void Use(Action<T> action);
}
}
Code part 2:
/// <summary>
/// Helper class to fix the WCF Client Proxy usage bug with IDispose.
/// Check: http://benmccallum.wordpress.com/2011/08/27/wcf-web-service-wrapper-closing-disposing-and-aborting-best-practices/
/// </summary>
/// <typeparam name="T"></typeparam>
public class ProxyService<T> : IProxyService<T>
{
public void Use(Action<T> action)
{
<cut>....
}
}
Code part 3:
public class AuthenticationFacade : IAuthenticationFacade
{
private readonly IProcessManager processManager;
private readonly ISessionWrapper sessionWrapper;
private readonly IProxyService<IAuthentication> authenticationProxyService;
public AuthenticationFacade(
IProcessManager processManager,
ISessionWrapper sessionWrapper,
IProxyService<IAuthentication> authenticationProxyService)
{
this.processManager = processManager;
this.sessionWrapper = sessionWrapper;
this.authenticationProxyService = authenticationProxyService;
}
public bool ValidateGebruiker(string gebruikernaam, string wachtwoord)
{
bool authenticated = false;
authenticationProxyService.Use(client =>
{
var sessionId = processManager.GetSessionId();
authenticated = client.ValidateGebruiker(
sessionId,
gebruikernaam,
wachtwoord);
});
return authenticated;
}
Code part 4:
public class AuthenticationFacadeFixture
{
public IProcessManager ProcessManager { get; set; }
public ISessionWrapper SessionWrapper { get; set; }
public IProxyService<IAuthentication> AuthenticationProxyService { get; set; }
public AuthenticationFacade CreateSut()
{
ProcessManager = new Mock<IProcessManager>().Object;
SessionWrapper = new Mock<ISessionWrapper>().Object;
AuthenticationProxyService = new Mock<IProxyService<IAuthentication>>().Object;
return new AuthenticationFacade(ProcessManager, SessionWrapper, AuthenticationProxyService);
}
}
Code part 5:
public static class MockExtensions
{
public static Mock<T> AsMock<T>(this T obj) where T : class
{
return Mock.Get(obj);
}
}
Code part 6 (unit test):
[TestMethod]
public void ValidateGebruiker_calls_processmanager_getsessionid_once()
{
// Arrange
var fixture = new AuthenticationFacadeFixture();
var sut = fixture.CreateSut();
var validUserPass = CreateValidGebruikersnaamWachtwoord();
// Act
sut.ValidateGebruiker(validUserPass.Gebruikersnaam, validUserPass.Wachtwoord);
// Assert
fixture.ProcessManager.AsMock().Verify(pm => pm.GetSessionId(), Times.Once());
}
You've omitted your Moq setup code which makes this a little harder, but I believe it looks something like this:
AuthenticationProxyService.Setup(a => a.Use(It.IsAny<Action<IAuthentication>>()));
If so, you can do the following:
// Not sure if you have this mock already, this is the "client" variable
// in your Use method action
Mock<IAuthentication> mockAuthentication = mockRepository.Create<IAuthentication>();
AuthenticationProxyService.Setup(a => a.Use(It.IsAny<Action<IAuthentication>>()))
.Callback<Action<IAuthentication>>(a => a(mockAuthentication.Object));
The Callback method receives the parameter from the Setup (an Action<IAuthentication>) which in this case is the code in ValidateGebruiker, and just invokes it with a mocked IAuthentication object (which you'll need to Setup if you don't already).

Unit Testing of a static factory method containing logic

before I begin with my question I want to point out that I am aware that there are tons of similar questions on stack overflow. Unfortunately none of these questions helped me finding a good solution in my concrete scenario.
The Problem:
I want to write a unit test for a static factory method which contains logic. I am looking for a way to unit test this method even if it is static. If that is not possible maybe someone can point out a better design for my class under test. I also considered using IoC but couldn't see the advantage considering unit-testing.
The Code:
public class Db
{
private XmlMapping mapping;
public static Db<T> Create()
{
var mapping = XmlMapping.Create(typeOf(T).Name);
return new Db(mapping);
}
private Db(XmlMapping mapping)
{
this.mapping = mapping;
}
}
public class XmlMapping //class under test
{
public static XmlMapping Create(string filename) //method under test
{
try
{
ValidateFilename(filename);
//deserialize xml to object of type XmlMapping
var result = Deserialize(filename);
if (result.IsInValid())
throw Exception()
return result;
}
catch (Exception)
{
throw new DbException();
}
}
}
The method Create which I want to unit test is within the class XmlMapping. This method serializes a xml file and generates an object of type XmlMapping. I tried to write a stub for the serialization part. But didn't want to call my Database Factory with a Mapping class in the constructor (constructor injection).
Edit:
My database factory is generic. The generic type is used to figure out which xml file should be louded i.e.: typeOf(T) = Customer --> XmlMapping-File = Customer.xml
The Solution (Thx to Jeff!):
public class XmlMapping : IMapping //class under test
{
internal static Func<Type, IMapping> DeserializeHandler { get; set; }
static XmlMapping()
{
DeserializeHandler = DeserializeMappingFor;
}
public static IMapping Create(Type type)
{
try
{
var mapping = DeserializeHandler(type);
if (!mapping.IsValid())
throw new InvalidMappingException();
return mapping;
}
catch (Exception ex)
{
throw new DataException("Failed to load mapping configuration from xml file.", ex);
}
}
internal XmlMapping(IMapping mapping)
{
this.Query = mapping.Query;
this.Table = mapping.Table;
this.Entity = mapping.Entity;
this.PropertyFieldCollection = mapping.PropertyFieldCollection;
}
private XmlMapping() { }
}
[TestClass]
public class MappingTests //testing class
{
[TestMethod]
public void Create_ValidDeserialization_ReturnsObjectInstance()
{
XmlMapping.DeserializeHandler = MakeFakeHandlerFor(MakeMappingStub());
var result = XmlMapping.Create(typeof(ActivityDto));
Assert.IsInstanceOfType(result, typeof(XmlMapping));
}
}
I would use a fake action handler to assist in verifying the content of the call to deserialize. Let's add a Func delegate property and default that to your serialize method. Your XmlMapping class and test would like something like:
public class XmlMapping //class under test
{
static XmlMapping()
{
// Default the handler to the normal call to Deserialize
DeserializeHandler = Deserialize;
}
public static XmlMapping Create(string filename) //method under test
{
//deserialize xml to object of type XmlMapping
//preudocode:
var result = DeserializeHandler(string.Format("{0}.xml",filename));
//...
return result;
}
// Abstract indirection function to allow you to swap out Deserialize implementations
internal static Func<string, XmlMapping> DeserializeHandler { get; set; }
private static XmlMapping Deserialize(string fileName)
{
return new XmlMapping();
}
}
public class CreateTests {
public void CallingDeserializeProperly()
{
// Arrange
var called = false;
Func<string, XmlMapping> fakeHandler = (string f) =>
{
called = true; // do your test of the input and put your result here
return new XmlMapping();
};
// Act
XmlMapping.DeserializeHandler = fakeHandler;
var m = XmlMapping.Create("test");
// Assert
Assert.IsTrue(called);
}
}

How can I get StructureMap's AutoMocker to mock fake data?

I'm currently trying to implement StructureMap's AutoMocking functionality and I need help with getting the mocked .
I have a Test method as follows:
[Test]
public void DirctoryResult_Returns_Groups()
{
var autoMocker = new RhinoAutoMocker<GroupController>(MockMode.AAA);
GroupController controller = autoMocker.ClassUnderTest;
var directoryResult = controller.DirectoryResult("b");
var fundDirectoryViewModel = (FundDirectoryViewModel)directoryResult.ViewData.Model;
Assert.IsNotNull(fundDirectoryViewModel.Groups);
}
Currently the test is failing because fundDirectoryViewModel.Groups is null.
The real implementation of DirectoryResult is as follows:
private readonly IGroupService _groupService;
public PartialViewResult DirectoryResult(string query)
{
return PartialView(new FundDirectoryViewModel
{
Groups =_groupService.GetGroupsByQuery(query)
});
}
where _groupService.GetGroupsByQuery(query) uses an interface to IGroupRepository to read data from the database. Of course, I don't want my test to read data from the actual database, but can somebody tell me how to get mock data for it?
What do I need to do to get the AutoMocker to mock the fake data for me?
update:
for reference, this is the definition of GroupService & GroupRepository
public class GroupService : IGroupService
{
private readonly IGroupRepository _groupRepository;
public GroupService(IGroupRepository groupRepository)
{
_groupRepository = groupRepository;
}
public IList<CompanyGroupInfo> GetGroupsByQuery(string query)
{
return _groupRepository.GetGroupsByQuery(query);
}
}
public class GroupRepository : DataUniverseRepository, IGroupRepository
{
public GroupRepository(ISession session)
{
_session = session;
}
public IList<CompanyGroupInfo> GetGroupsByQuery(string query)
{
// dig into the database and return stuff with _session..
}
}
I've been informed that the question was wrong. Automocker doesn't mock data like that. It's up to me to specify the fake data with Rhino Mocks.
This works:
[Test]
public void DirctoryResult_Returns_Groups()
{
var service = autoMocker.Get<IGroupService>();
service.Expect(srv => srv.GetGroupsByQuery(Arg<string>.Is.Anything))
.Return(new List<CompanyGroupInfo>
{
new CompanyGroupInfo(),
new CompanyGroupInfo(),
new CompanyGroupInfo()
});
service.Replay();
var directoryResult = _controller.DirectoryResult("b");
var fundDirectoryViewModel = (FundDirectoryViewModel)directoryResult.ViewData.Model;
Assert.That(fundDirectoryViewModel.Groups.Count, Is.EqualTo(3));
service.AssertWasCalled(srv => srv.GetGroupsByQuery(Arg<string>.Is.Equal("b")));
}

Categories