Unit Testing Interface and abstract memebers using shims in Visual Studio 2013 - c#

I have below code which I want to unit test.
public abstract class Manager : MyPermissions, IManager
{
public IManager empManager { get; set; }
public void UpdatePermission()
{
if (empManager != null)
empManager.UpdatePermissions();
}
}
I don't have an class that derives from the above class within the same library otherwise I would have preferred to test the derived class for testing the above code. For now I have below test which I am running but it actually doesn't hit the actual code for testing.
[TestMethod]
public void empManagerGetSet()
{
using (ShimsContext.Create())
{
StubIManager sManager;
sManager = new StubIManager();
sManager.empManagerGet = () => { return (IManager)null; };
var result = sManager.empManagerGet;
Assert.IsNotNull(result);
}
}
Is there any other approach I can use to write a better UT in this scenario?

You don't say what your MyPermissions class looks like, if it has a constructor and if so what it does.. so this might not be the right approach. Note, you'd also need to implement stubs for any abstract methods defined in the Manager class.
If you just want to test the empManager property, you can just create a testable derived type in your test project and test the properties on that. This would give you something like this:
class TestableManager : Manager {
}
Then have a test something like this:
[TestMethod]
public void TestManagerPropertyRoundTrip {
var sut = new TestableManager();
Assert.IsNull(sut.empManager);
sut.empManager = sut;
Assert.AreEqual(sut, sut.empManager);
}
You can also test any other methods on the Manager class, via the TestableManager, since it only exists to make the class concrete.
There's a suggestion in the comments on your question that there is no point testing public properties. This is somewhat opinion based. I tend to take the view that if you were following a test first based approach, you wouldn't necessarily know that the properties were going to be implemented using auto properties, rather than a backing field. So, the behaviour of being able to set a property and retrieve it again is something that I would usually test.

Related

Proper use of internal class when testing with generic base test class

TL;DR
I can't seem to get InternalsVisibleTo to work with my Unit Tests
Background
I'm currently developing a library where I'd like to make some (but not all) classes internal to avoid confusing the users. Only SOME of the classes should be public from that dll.
I figured this would be a good project to learn how to deal with the internal keyword in C#.
Whenever I make a new project, I find myself using a variant of DDD, where I'll split up responsibilities into different DLL's, but for the sake of this question, think of my project structure like this (from top to bottom):
The executable using my library
The library that I'm developing
A unit test library for unit-testing my library
Testing tools library, containing base class for all unit tests
For a working example of the architecture, you can look at my HelloWorld project over on github. This example does not replicate the problem here though, it only serves to illustrate how I typically layer my code.
I'll often create a base class for my unit tests that creates mocks for any type that I'm testing, i.e. this example:
public class TestsFor<TInstance> where TInstance : class
{
protected MoqAutoMocker<TInstance> AutoMock { get; set; }
protected TInstance Instance { get; set; }
public TestsFor()
{
AutoMock = new MoqAutoMocker<TInstance>();
RunBeforeEachUnitTest(); // virtual
Instance = AutoMock.ClassUnderTest;
RunAfterEachUnitTest(); // virtual
}
}
Problem
The Unit-Tests that I write often take them form of:
public class ReportServiceTests : TestsFor<ReportService>
{
[Fact]
public async Task CreateReport_WhenCalled_LogsTheCall()
{
// Act
await Instance.CreateReport();
// Assert
GetMockFor<ILogger>().Verify(logger => logger.Enter(Instance, nameof(Instance.CreateReport)), Times.Once());
}
}
Where each Unit test will derive the TestsFor<T> class in order to give me an out-of-the-box mocked test class. However, even though I've marked my internal classes with InternalsVisibleTo pointing them to both the unit-test assembly as well as the test-tools assembly (where the unit-test baseclass is) I'm STILL getting Inconsistent accessibility errors.
Does anyone know how to get around this?
The problem you're running into is that you are trying to create a class that is more accessible than its base class.
You can delegate instead of deriving:
public class ReportServiceTests
{
private Tests tests = new Tests();
[Fact]
public async Task CreateReport_WhenCalled_LogsTheCall()
{
tests.CreateReport_WhenCalled_LogsTheCall();
}
private class Tests : TestsFor<ReportService>
{
public async Task CreateReport_WhenCalled_LogsTheCall()
{
// Act
await Instance.CreateReport();
// Assert
GetMockFor<ILogger>().Verify(logger => logger.Enter(Instance, nameof(Instance.CreateReport)), Times.Once());
}
}
}

Need to create fakes for a class that manipulates the results of interface in microsoft unit testing tool using c#

I need to implement fakes for unit testing one of my methods. Problem is the method I need to test calls a class method and retrieves some system parameters.Scenario is as below:
Class A(){
public void method xx(){
//This needs to be tested.
//This method makes a call to retrieve some informations. The call is like
below:
String culture=Api.GetEnvironmentData().GetCulture();
//This is the problem area.
boolean implmentApi=Api.GetEnvironmentData().DoImplmentApi();
//This is the problem area.
}
}
This GetEnvironmentData method is something like this:
public static EnvironmentData GetEnvironmentData ()
{
return GetDiContainer().Resolve<EnvironmentData >();
}
EnvironmentData class is something like this:
public class EnvironmentData(){
public EnvironmentData(IEnvironmentDataProvider EnvironmentDataProvider){
//
}
}
I can fake the IEnvironmentDataProvider using moq but am not able to figure out how to fake the EnvironmentData class. I need to fake the EnvironmentData class because it manipulated the results of IEnvironmentDataProvider based of various method calls. For example both GetCulture and DoImplmentApi call the getData method of the interface IEnvironmentDataProvider and then cast them accordingly.
Now when I fake the IEnvironmentDataProvider and return some value I am not able to control what to return when GetCulture and when DoImplmentApi is called.
Can some one suggest how to implement the fakes for the above scenario.
You don't need to mock dependencies of EnvironmentData class. I see one problem here: you are using DI container, like Service Locator, which in this scenario behave like antipattern. All dependencies should be injected, e. g.: by constructor or property.
Change your Api class to something like this:
public class Api
{
private readonly EnvironmentData _environmentData;
public Api(EnvironmentData envData)
{
environmentData = envData;
}
public string GetCulture()
{
return _envData.GetCulture();
}
}
Remember that implementation details of Api class should be hidden. You shouldn't expose EnvironmentData in this scenario. Api class should ask for all dependencies which are needed to implement this class and has own interface.
Based on your comments, I think your best shot is to wrap the static class in a facade. Then you can mock the facade.
Something like this:
Class A
{
IEnvironmentDataFacade _environmentDataFacade;
Class A(IEnvironmentDataFacade environmentDataFacade)
{
_environmentDataFacade = environmentDataFacade;
}
public void method xx()
{
//Now you can fake IEnvironmentDataFacade:
String culture= _environmentDataFacade.GetCulture();
//Do the same as above with the method here:
boolean implmentApi=Api.GetEnvironmentData().DoImplmentApi();
//This is the problem area.
}
}
public class EnvironmentDataFacade : IEnvironmentDataFacade
{
public string GetCulture()
{
return Api.GetEnvironmentData().GetCulture();
}
}
public interface IEnvironmentDataFacade
{
string GetCulture();
}

Unit testing extension methods, had a go, is this right, or gone around the houses?

I have my POCO library and i have entities that implement an interface called IEntityDelete.
Interface is very simple, looks something like this
public interface IEntityDelete
{
bool IsDeleted { get; set; }
}
So i have an entity that implements this interface, again very simple, looks something like this
public class MyEntity() : IEntityDelete
{
public bool IsDeleted { get; set; }
}
I have an extension method, which i created this like
public static void MarkAsDeleted(this IEntityDelete entity)
{
entity.IsDeleted = true;
}
Then i needed to check if this method was being called within one of my service methods in my unit tests. Service method is very basic, looks something like this.
public Task<int> DeleteByFlagAsync(MyEntity entity)
{
entity.MarkAsDeleted();
return _context.SaveChangesAsync();
}
Apparently you cannot test extension methods easily, without using Microsofts Moles framework, but i do not want another dependency.
I did some googl'ing and found 2 articles on this, and how to do about it, and would like to know if this is correct, or whether i have done something stupid.
Two articles i found where
http://adventuresdotnet.blogspot.co.uk/2011/03/mocking-static-methods-for-unit-testing.html
http://blogs.clariusconsulting.net/kzu/how-to-mock-extension-methods/
They recommend using a wrapper class which aint static, so i ended up with this.
First created my wrapper interface
public interface IEntityDeleteWrapper
{
void MarkAsDeleted(IEntityDelete entity);
}
Create a class that implements this interface
public class EntityDeleteWrapper : IEntityDeleteWrapper
{
public void MarkAsDeleted(IEntityDelete entity)
{
entity.IsDeleted = true;
entity.DeletedDate = DateTime.Now;
entity.DeletedByUserId = 546372819;
}
}
Inject this interface into my service constructor
public MyService(IEntityDeleteWrapper deleteWrapper)
{
_deleteWrapper = deleteWrapper;
}
Change my service method call to use the wrapper like so
public Task<int> DeleteByFlagAsync(MyEntity entity)
{
_deleteWrapper.MarkAsDeleted(entity);
return _context.SaveChangesAsync();
}
SOLVED
As i was told, this was way too far to go, i can just check if a property has changed. In light of this, i am using my extension method still and updated my unit test to this.
[TestMethod]
public void should_mark_entity_as_deleted()
{
// arrange
var entity = new Attachment
{
IsDeleted = false
};
// act
var result = _service.DeleteByFlagAsync(entity).Result;
// assert
Assert.AreEqual(true, entity.IsDeleted);
_context.Verify(e => e.SaveChangesAsync(), Times.Once);
}
You went too far. Your test should verify observable change to state, not how that change was made. Otherwise you make your tests very brittle, not to mention you add rather unnecessary extra layer. It would be enough to check whether entity properties changed after DeleteByFlagAsync call.
Of course, when deleting gets more complex introducing dependency to delegate this task to makes sense. But then, few questions arise:
What would be the scope of DeleteByFlagAsync? Call two dependencies?
Would it be practical to test it?
...or perhaps tests for said dependency would suffice (as this is where the actual mark-for-deletion will take place)?

How to Mock construction of new objects through Nunit

I want to write a nunit test to test a method but I am not able to mock an object instantiated inside that method.
Here is the code:
public class Converter()
{
public void modifyScore(string convertTo){
ScoreConverter scoreConverter;
if(convertTo.Equals("decimal"){
scoreConverter = new DecimalScoreConverter();
scoreConverter.determineScore();
}
else{
scoreConverter = new IntegerScoreConverter();
scoreConverter.determineScore();
}
}
I want to write a test for modifyScore and want to test which object's method has called.
How can I test this method using nunit?
First of all you should start working against abstractions.
I think this is needed for all mock frameworks.
From the info you gave me, and a couple of assumptions:
Anyway, here we go:
public Interface IConverter
{
IScoreConverter ScoreConverter { get; set; };//use constructorinjection instead
void ModifyScore(string convertTo);
}
public Interface IScoreConverter
{
DetermineScore();
}
I would recommend taking a look at MoQ.
You need to figure out what you want to be returned by the inner object.
For now you don't return any value from ModifyScore, so you have nothing to test.
If you would return e.g. a string, the test could look like this:
var scoreConverterResponse = "theStringYouWantToBeReturned"
var scoreConverterMock = new Mock<IScoreConverter>();
scoreConverterMock.Setup(sc => sc.DetermineScore())
.Returns(scoreConverterResponse);
scoreConverterMock.Verify(sc => sc.DetermineScore(It.IsAny<string>()), Times.AtLeastOnce());
I fixed the naming conventions toom i.e. CamelCase methods.
I wrote this on the fly, so I apologise if there are compile errors.
Unit tests are mostly based on state change. So, the natural course is to:
Do something on a class
Test whether the state of the class changed as expected
Maybe you can consider a change in your code to test the type of scoreConverter:
public class Converter
{
public ScoreConverter scoreConverter { get; set; }
public void modifyScore(string convertTo){
if(convertTo.Equals("decimal"){
scoreConverter = new DecimalScoreConverter();
}
else{
scoreConverter = new IntegerScoreConverter();
}
scoreConverter.determineScore();
}
Your test can then execute the modifyScore() method, and then Assert the type of scoreConverter variable.
If you don't want to make the property public, another option is to make it internal and then add the InternalsVisibleToAttribute, or maybe to use a Factory class and then mock it in the test, as amcdermott pointed out.
Greetings!

Mock set an attribute that doesn't have a set

Hi everyone smarter than me :-) I have another application which requires generation of an abstract class, and due to testing purposes is quite difficult to debug. therefor i created a wrapper and can define my abstract classes in visual Studio now (instead of native application)
However, the native application is expecting public abstract [obj type] values with only a get; method, and if i put in a set;, the application will bomb. Is there any way to set a field using Reflection or Mock to this field, and NOT have the set method?
//simplified class
public abstract class GetEUserAndDetails : [app specific interfaces]
{
public abstract Metastorm.Runtime.Types.Text paramFullNameLike
{
get;
set; //note: If i have this here, it will fail in Metastorm
}
public System.Data.DataSet Read()
{
//do something
}
}
and in Main() it's a c# winform, i have
Mock<Metastorm.Runtime.Models.MySampleProject.GetEUserAndDetails> mockMyBO = new Mock<Metastorm.Runtime.Models.MySampleProject.GetEUserAndDetails>() { CallBase = true };
//using reflection
foreach (PropertyInfo pi in mockMyBO.Object.GetType().GetProperties())
{
//simplified again, another form getting parameters and such
pi.SetValue(mockMyBO.Object, form.myTextParam, null);
}
If I don't have the set method, the pi.SetValue() line will fail, but if i do, it will fail in the native app. (note: i'm using the same test harness to test all sorts of abstract classes that will all implement the Read() method and need to test that it is pulling the correct data back, but the parameters will be different for each class.
Sorry if my code is bad i couldn't get it to format properly, and also please bear with me if i used the wrong terms. I'm not an expert by any means, just enough to be dangerous. I am just living with leaving the set; line for the moment and manually removing it before copy/pasting into the main application, but would like to find another way to do this for when there are many params.
If I understood your scenario correctly, you actually want to test the code in the abstract class, and not mock it.
With that in mind, I think the easiest approach in this case is simply to create a subclass within your test, that will inherit from your base class, and implement whatever is necessary for you to be able to test the base class.
Such as:
public class GetUserAndDetailsImplementation : GetEUserAndDetails
{
private Metastorm.Runtime.Types.Text _paramFullNameLike;
public override Metastorm.Runtime.Types.Text paramFullNameLike
{
get { return _paramFullNameLike; }
}
public void SetParamFullNameLike(Metastorm.Runtime.Types.Text text)
{
_paramFullNameLike = text;
}
}
And you can use that class as entry point for your testing.
Now if you really want to use a mock, have you tried the following?
var mock = new Mock<GetEUserAndDetails> { CallBase = true };
mock.SetupGet(x => x.paramFullNameLike).Returns(<some value>);

Categories