Testing that serializable attributes are set - c#

I'm writing a unit test to verify that the serializable attributes are set on my class. I thought I was on the right way, but for some reason I can't find the attribute types.
Here is my class:
[DataContract]
public class User
{
[DataMember]
public int Id { get; set; }
}
And a unit test for checking the attributes:
[Test]
public void DataMembersSetAsExpected()
{
var type = typeof(User);
Assert.That(type.IsDefined(typeof(System.Runtime.Serialization.DataContractAttribute), true));
var idProperty = type.GetProperty("Id");
Assert.That(idProperty.IsDefined(typeof(System.Runtime.Serialization.DataMemberAttribute), true));
}
The problem here is that the types of the attributes are unknown. Where can I find the right attribute definitions?
System.Runtime.Serialization.DataContractAttribute
System.Runtime.Serialization.DataMemberAttribute

Add a reference to System.Runtime.Serialization.dll.

You need to reference the System.Runtime.Serialization assembly in your unit test project.

I have a Fixture class that I use for unit testing (test data generator) and I have made these extension methods for it:
public static void SutPropertyHasAttribute<TSut, TProperty>(this Fixture fixture, Expression<Func<TSut, TProperty>> propertyExpression, Type attributeType)
{
var pi = (PropertyInfo)((MemberExpression)propertyExpression.Body).Member;
var count = pi.GetCustomAttributes(attributeType, true).Count();
Assert.AreEqual(1, count);
}
public static void SutHasAttribute<TSut>(this Fixture fixture, Type attributeType)
{
var type = typeof(TSut);
var count = type.GetCustomAttributes(attributeType, true).Count();
Assert.AreEqual(1, count);
}
public static void SutMethodHasAttribute<TSut>(this Fixture fixture, Expression<Action<TSut>> methodExpression, Type attributeType)
{
var mi = (MethodInfo)((MethodCallExpression)methodExpression.Body).Method;
var count = mi.GetCustomAttributes(attributeType, true).Count();
Assert.AreEqual(1, count);
}
Now I call it like this from my tests:
[TestMethod]
public void SutHasDataContractAttribute()
{
// Fixture setup
// Exercise system and verify outcome
new Fixture().SutHasAttribute<Flag>(typeof(DataContractAttribute));
// Teardown
}
[TestMethod]
public void FlagGroupIdHasDataMemberAttribute()
{
// Fixture setup
// Exercise system and verify outcome
new Fixture().SutPropertyHasAttribute((Flag f) => f.FlagGroupId, typeof(DataMemberAttribute));
// Teardown
}
The Flag class looks like this:
[DataContract(Namespace ="http://mynamespace")]
public class Flag
{
[DataMember]
public string FlagGroupId { get; set; }
}
Of course you need a reference to System.Runtime.Serialization like this:
using System.Runtime.Serialization;

Related

How to do the Assert phase of a private method whose return type is Void?

I have a class with a private method
public class MyClass
{
private void SomeMethod(PrimaryAllocationDP packet)
{
........................
some code
........................
packet.AllocatedAgency = AgencyAllocated;
}
}
Now by using MSUnit Testing framework, I have written so far
[TestMethod]
public void TestAllocatedAgency()
{
var packet = new Fixture().Create<PrimaryAllocationDP>(); //used AutoFixture here
PrivateObject accessor = new PrivateObject(new MyClass());
accessor.Invoke("SomeMethod", packet); //Act
// what will be the Assert? Since it is void
}
What will be the Assert? Since it is void, how can I write the assert?
Well given that in the example the method under test is making a change to its argument/dependency you could assert that the desired result of calling the function is that the packet's AllocatedAgency property is in fact not null
[TestMethod]
public void TestAllocatedAgency() {
//Arrange
var packet = new Fixture().Create<PrimaryAllocationDP>(); //used AutoFixture here
var sut = new MyClass();
var accessor = new PrivateObject(sut);
//Act
accessor.Invoke("SomeMethod", packet);
//Assert
Assert.IsNotNull(packet.AllocatedAgency);
}
If it is possible for you to change PrimaryAllocationDP you can also add a new interface IPrimaryAllocationDP and test the property setting. In my test I am assuming AllocatedAgency is of type object and I am using Moq. But maybe you can also use AutoFixture for mocking? To make it more clear I set AgencyAllocated directly in MyClass
[TestFixture]
public class DependencyInjection
{
[TestMethod]
public void TestAllocatedAgency()
{
var packet = new Mock<IPrimaryAllocationDP>();
PrivateObject accessor = new PrivateObject(new MyClass());
accessor.Invoke("SomeMethod", packet.Object); //Act
packet.VerifySet(p => p.AllocatedAgency = 42);
}
}
public interface IPrimaryAllocationDP
{
//object or any other type
object AllocatedAgency { set; }
}
public class PrimaryAllocationDP : IPrimaryAllocationDP
{
public object AllocatedAgency { set; private get; }
}
public class MyClass
{
private readonly object AgencyAllocated = 42;
private void SomeMethod(IPrimaryAllocationDP packet)
{
//........................
//some code
//........................
packet.AllocatedAgency = AgencyAllocated;
}
}

Unit Testing Custom Assertion Class - Failure Case

I have a custom assertion class that I'm currently unit testing.
public static class AssertionExtensions
{
public static void ShouldHaveAttributeApplied<T>(this T obj, Type attributeType)
{
Assert.IsNotNull(Attribute.GetCustomAttribute(typeof(T), attributeType));
}
}
The tests for this class are:
[TestMethod]
public void When_Called_For_Class_Validates_Pass_Correctly()
{
var obj = new FakeClass();
obj.ShouldHaveAttributeApplied(typeof(FakeClassAttribute));
}
[TestMethod]
public void When_Called_For_Class_Validates_Fail_Correctly()
{
var obj = new FakeClass();
obj.ShouldHaveAttributeApplied(typeof(UnappliedFakeClassAttribute));
}
The test When_Called_For_Class_Validates_Fail_Correctly fails as expected, but how do I mark this fail as a pass in the test suite?
This is using C# / MSTest.
Adding the ExpectedException attribute with the exception set to AssertionFailedException makes the test pass as intended.
Usage:
[TestMethod]
[ExpectedException(typeof(AssertFailedException))]
public void When_Called_For_Class_Validates_Fail_Correctly()
{
var obj = new FakeClass();
obj.ShouldHaveAttributeApplied(typeof(UnappliedFakeClassAttribute));
}

Limiting Scope of UnitTest using Rhino stubs

I'm working on a unit test for a service method, that has dependencies. Simplified:
public class ConditionChecker
{
private SqlConnection _connection;
public bool CanDoSomething()
{
return _connection.State == ConnectionState.Open;
}
}
public class A
{
public ConditionChecker Checker { get; set; }
public bool CanInvokeA()
{
return Checker.CanDoSomething();
}
}
[TestClass]
public class ATests
{
[TestMethod]
public void TestCanInvokeA()
{
// arrange
A a = new A();
ConditionChecker checker = MockRepository.GenerateStub<ConditionChecker>();
checker.Stub(x => x.CanDoSomething()).Return(true);
a.Checker = checker;
// act
bool actual = a.CanInvokeA();
// assert
Assert.AreEqual(true, actual);
}
}
What I want is to completely bypass the implementation of ConditionChecker.CanDoSomething, which is why I stub the call, still I run into a null reference Exception during my test, since the _connection member is not set. What am I doing wrong here?
You just mark your method as virtual, it will work:
public virtual bool CanDoSomething()
{
}
Since behind the scene Rhino Mock will create a dynamic proxy for ConditionChecker, so you need to mark virtual to allow Rhino Mock to override it.

How to return null when accessing a moq object?

I am using Moq library for unit testing. Now what i want is that when I access my object for the first time it should return null, and when i access this on second time it should return something else.
here is my code
var mock = new Mock<IMyClass>();
mock.Setup(?????);
mock.Setup(?????);
var actual = target.Method(mock.object);
in my method i am first checking that whether mock object is null or not, if it is null then do initialize it and then do some calls on it.
bool Method(IMyClass myObj)
{
if (myObj != null)
return true;
else
{
myObj = new MyClass();
bool result = myObj.SomeFunctionReturningBool();
return result;
}
}
what to do setup for mock object,
Also i need to know how to mock this line
bool result = myObj.SomeFunctionReturningBool();
It sounds like you are trying to run two tests with one test method - maybe it would be better to split the tests into two?
You also want to initialise a new object if the method is passed null. To test this, I suggest creating a factory object responsible for creating instances of MyClass. The new code would look like:
interface IMyClassFactory
{
IMyClass CreateMyClass();
}
bool Method(IMyClass myObj, IMyClassFactory myClassFactory)
{
if (myObj != null)
{
return true;
}
myObj = myClassFactory.CreateMyClass();
return myObj.SomeFunctionReturningBool();
}
Then the tests would look like:
[Test]
public void Method_ShouldReturnTrueIfNotPassedNull()
{
Assert.That(target.Method(new MyClass()), Is.True);
}
[Test]
public void Method_ShouldCreateObjectAndReturnResultOfSomeFunctionIfPassedNull()
{
// Arrange
bool expectedResult = false;
var mockMyClass = new Mock<IMyClass>();
mockMyClass.Setup(x => x.SomeFunctionReturningBool()).Returns(expectedResult);
var mockMyFactory = new Mock<IMyClassFactory>();
mockMyFactory.Setup(x => x.CreateMyClass()).Returns(mockMyClass.Object);
// Act
var result = target.Method(null, mockMyFactory.Object);
// Assert
mockMyClass.Verify(x => x.SomeFunctionReturningBool(), Times.Once());
mockMyFactory.Verify(x => x.CreateMyClass(), Times.Once());
Assert.That(result, Is.EqualTo(expectedResult));
}
Here the factory pattern has been used to pass in an object which can create objects of IMyClass type, and then the factory itself has been mocked.
If you do not want to change your method's signature, then create the factory in the class's constructor, and make it accessible via a public property of the class. It can then be overwritten in the test by the mock factory. This is called dependency injection.
Moq - Return null - This working example simply illustrates how to return null using Moq. While the line of code is required is the commented line below, a full working example is provided below.
// _mockShopService.Setup(x => x.GetProduct(It.IsAny<string>())).Returns(() => null);
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
}
public interface IShopService
{
Product GetProduct(string productId);
}
public class ShopService : IShopService
{
public Product GetProduct(string productId)
{
if (string.IsNullOrWhiteSpace(productId))
{
return new Product();
}
return new Product { Id = "8160807887984", Name = "How to return null in Moq" };
}
}
public class Shop
{
private static IShopService _shopService;
public Shop(IShopService shopService)
{
_shopService = shopService;
}
public Product GetProduct(string productId)
{
Product product = _shopService.GetProduct(productId);
return product;
}
}
[TestClass]
public class ShopTests
{
Mock<IShopService> _mockShopService;
[TestInitialize]
public void Setup()
{
_mockShopService = new Mock<IShopService>();
}
[TestMethod]
public void ShopService_GetProduct_Returns_null()
{
//Arrange
Shop shop = new Shop(_mockShopService.Object);
//This is how we return null --- all other code above is to bring this line of code home
_mockShopService.Setup(x => x.GetProduct(It.IsAny<string>())).Returns(() => null);
//Act
var actual = shop.GetProduct(It.IsAny<string>());
//Assert
Assert.IsNull(actual);
}
}
To mock a result value you can do simply:
mock.Setup(foo => foo.SomeFunctionReturningBool()).Returns(true); // or false :)
for the other question, just pass null in the unit test instead of passing mock.object and your unit test cover that too. So you basically create two unit test one with:
var actual = target.Method(mock.object);
and the other one with:
var actual = target.Method(null);
Currently your SUT is tight-coupled with MyClass implementation. You can't mock objects which are instantiated with new keyword inside your SUT. Thus you cannot test your SUT in isolation, and your test is not unit test anymore. When implementation of MyClass.SomeFunctionReturningBool will change (it will return true instead of false), tests of your SUT will fail. This shouldn't happen. Thus, delegate creation to some dependency (factory) and inject that dependency to your SUT:
[Test]
public void ShouldReturnTrueWhenMyClassIsNotNull()
{
Mock<IMyClassFactory> factory = new Mock<IMyClassFactory>();
Mock<IMyClass> myClass = new Mock<IMyClass>();
var foo = new Foo(factory.Object);
Assert.True(foo.Method(myClass.Object));
}
[Test]
public void ShouldCreateNewMyClassAndReturnSomeFunctionValue()
{
bool expected = true;
Mock<IMyClass> myClass = new Mock<IMyClass>();
myClass.Setup(mc => mc.SomeFunctionReturningBool()).Returns(expected);
Mock<IMyClassFactory> factory = new Mock<IMyClassFactory>();
factory.Setup(f => f.CreateMyClass()).Returns(myClass.Object);
var foo = new Foo(factory.Object);
Assert.That(foo.Method(null), Is.EqualTo(expected));
factory.VerifyAll();
myClass.VerifyAll();
}
BTW assignment new value to method parameter does not affect reference which you passed to method.
Implementation:
public class Foo
{
private IMyClassFactory _factory;
public Foo(IMyClassFactory factory)
{
_factory = factory;
}
public bool Method(IMyClass myObj)
{
if (myObj != null)
return true;
return _factory.CreateMyClass().SomeFunctionReturningBool();
}
}
You can use TestFixture with parameter. this test will run two times and different type value.
using NUnit.Framework;
namespace Project.Tests
{
[TestFixture(1)]
[TestFixture(2)]
public class MyTest
{
private int _intType;
public MyTest(int type)
{
_intType = type;
}
[SetUp]
public void Setup()
{
if (_intType==1)
{
//Mock Return false
}
else
{
//Mock Return Value
}
}
}
}

Creating a hybrid of a mock and an anonymous object using e.g. Moq and AutoFixture?

I encountered a class during my work that looks like this:
public class MyObject
{
public int? A {get; set;}
public int? B {get; set;}
public int? C {get; set;}
public virtual int? GetSomeValue()
{
//simplified behavior:
return A ?? B ?? C;
}
}
The issue is that I have some code that accesses A, B and C and calls the GetSomeValue() method (now, I'd say this is not a good design, but sometimes my hands are tied ;-)). I want to create a mock of this object, which, at the same time, has A, B and C set to some values. So, when I use moq as such:
var m = new Mock<MyObject>() { DefaultValue = DefaultValue.Mock };
lets me setup a result on GetSomeValue() method, but all the properties are set to null (and setting up all of them using Setup() is quite cumbersome, since the real object is a nasty data object and has more properties than in above simplified example).
So on the other hand, using AutoFixture like this:
var fixture = new Fixture();
var anyMyObject = fixture.CreateAnonymous<MyObject>();
Leaves me without the ability to stup a call to GetSomeValue() method.
Is there any way to combine the two, to have anonymous values and the ability to setup call results?
Edit
Based on nemesv's answer, I derived the following utility method (hope I got it right):
public static Mock<T> AnonymousMock<T>() where T : class
{
var mock = new Mock<T>();
fixture.Customize<T>(c => c.FromFactory(() => mock.Object));
fixture.CreateAnonymous<T>();
fixture.Customizations.RemoveAt(0);
return mock;
}
This is actually possible to do with AutoFixture, but it does require a bit of tweaking. The extensibility points are all there, but I admit that in this case, the solution isn't particularly discoverable.
It becomes even harder if you want it to work with nested/complex types.
Given the MyObject class above, as well as this MyParent class:
public class MyParent
{
public MyObject Object { get; set; }
public string Text { get; set; }
}
these unit tests all pass:
public class Scenario
{
[Fact]
public void CreateMyObject()
{
var fixture = new Fixture().Customize(new MockHybridCustomization());
var actual = fixture.CreateAnonymous<MyObject>();
Assert.NotNull(actual.A);
Assert.NotNull(actual.B);
Assert.NotNull(actual.C);
}
[Fact]
public void MyObjectIsMock()
{
var fixture = new Fixture().Customize(new MockHybridCustomization());
var actual = fixture.CreateAnonymous<MyObject>();
Assert.NotNull(Mock.Get(actual));
}
[Fact]
public void CreateMyParent()
{
var fixture = new Fixture().Customize(new MockHybridCustomization());
var actual = fixture.CreateAnonymous<MyParent>();
Assert.NotNull(actual.Object);
Assert.NotNull(actual.Text);
Assert.NotNull(Mock.Get(actual.Object));
}
[Fact]
public void MyParentIsMock()
{
var fixture = new Fixture().Customize(new MockHybridCustomization());
var actual = fixture.CreateAnonymous<MyParent>();
Assert.NotNull(Mock.Get(actual));
}
}
What's in MockHybridCustomization? This:
public class MockHybridCustomization : ICustomization
{
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(
new MockPostprocessor(
new MethodInvoker(
new MockConstructorQuery())));
fixture.Customizations.Add(
new Postprocessor(
new MockRelay(t =>
t == typeof(MyObject) || t == typeof(MyParent)),
new AutoExceptMoqPropertiesCommand().Execute,
new AnyTypeSpecification()));
}
}
The MockPostprocessor, MockConstructorQuery and MockRelay classes are defined in the AutoMoq extension to AutoFixture, so you'll need to add a reference to this library. However, note that it's not required to add the AutoMoqCustomization.
The AutoExceptMoqPropertiesCommand class is also custom-built for the occasion:
public class AutoExceptMoqPropertiesCommand : AutoPropertiesCommand<object>
{
public AutoExceptMoqPropertiesCommand()
: base(new NoInterceptorsSpecification())
{
}
protected override Type GetSpecimenType(object specimen)
{
return specimen.GetType();
}
private class NoInterceptorsSpecification : IRequestSpecification
{
public bool IsSatisfiedBy(object request)
{
var fi = request as FieldInfo;
if (fi != null)
{
if (fi.Name == "__interceptors")
return false;
}
return true;
}
}
}
This solution provides a general solution to the question. However, it hasn't been extensively tested, so I'd love to get feedback on it.
Probably there is a better why, but this works:
var fixture = new Fixture();
var moq = new Mock<MyObject>() { DefaultValue = DefaultValue.Mock };
moq.Setup(m => m.GetSomeValue()).Returns(3);
fixture.Customize<MyObject>(c => c.FromFactory(() => moq.Object));
var anyMyObject = fixture.CreateAnonymous<MyObject>();
Assert.AreEqual(3, anyMyObject.GetSomeValue());
Assert.IsNotNull(anyMyObject.A);
//...
Initially I tried to use fixture.Register(() => moq.Object); instead of fixture.Customize but it registers the creator function with OmitAutoProperties() so it wouldn't work for you case.
As of 3.20.0, you can use AutoConfiguredMoqCustomization. This will automatically configure all mocks so that their members' return values are generated by AutoFixture.
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
var mock = fixture.Create<Mock<MyObject>>();
Assert.NotNull(mock.Object.A);
Assert.NotNull(mock.Object.B);
Assert.NotNull(mock.Object.C);

Categories

Resources