Moqed method returning null instead of string - c#

I'm using Moq for some C# testing. For some reason, I'm getting a null back instead of a string. I'm trying to test
public void Foo(IData data){
_value = data.GetValue<T>(someString);
}
interface IData
{
T GetValue<T>(string someString);
}
and in my test code I have
Mock<IData> dataMock = new Mock<IData>();
dataMock.Setup(x => x.GetValue<string>(It.IsAny<string>())).Returns("blah");
Foo(dataMock.Object);
But when I step through, _value gets assigned null. Shouldn't it be assigned "blah"?

Most likely the generic T parameter in your call to GetValue is not string, so the Setup condition is not matched. By default Moq will return default values (null in this case) from method calls that haven't been explicitly Setup, unless you tell it to be "strict."
// tell Moq to throw an exception if someone calls a method that you haven't `Setup`
Mock<IData> dataMock = new Mock<IData>(MockBehavior.Strict);

Related

Moq - passing arguments from setup() to returns()

I am not sure how to pass arguments from Setup() to Returns() in Moq.
Here is an example:
public static IInterfaceHandler GetInterfaceHandlerMoq()
{
// Defining the moq
var moq = new Mock<IInterfaceHandler>();
// Trying to set up a moq using another moq
moq.Setup(m => m.CreateCommunicationInterface(It.IsAny<Guid>(), It.IsAny<string>()))
.Returns((Guid guid, string value) => GetProgrammerMoq(guid, value));
// Return mocked object
return moq.Object;
}
Note that GetProgrammerMoq() is a library that will return another Moq. Here is the code:
public static IProgrammer GetProgrammerMoq(Guid guid, string instName)
{
// Create Moq
var moq = new Mock<IProgrammer>();
// Set up the returnables
moq.Setup(o => o.InstanceName).Returns(programmer + "_" + instName);
moq.Setup(o => o.Guid).Returns(guid);
// Return mocked object
return moq.Object;
}
See here that GetProgrammerMoq() needs its arguments to be set up based on what is passed to CreateCommunicationInterface().
My test then tries to get and use the Moq, but "p" is returned as null (because, I guess, my arguments are not passed properly to Returns()).
Here is a draft of what the test is to look like:
[Fact]
public void DoSomething()
{
IInterfaceHandler test = ProgrammerMoqs.GetInterfaceHandlerMoq();
Guid? g = new Guid();
IProgrammer p = test.CreateCommunicationInterface(g, "test-boff");
...
}
Try this:
var moq = new Mock<IInterfaceHandler>(MockBehavior.Strict);
MockBehavior.Strict: if you get NULLs from Mock, then always try MockBehavior.Strict. When some setup is not prepared, Moq by default returns NULL. But with MockBehavior.Strict, it will throw an exception. Every single attempt to call anything from the mock object, if it lacks proper setup, will throw.
If you get an exception when trying MockBehavior.Strict, then it means that the:
.Setup(m => m.CreateCommunicationInterface(It.IsAny<Guid>(), It.IsAny<string>()))
failed to catch the invocatio, so the mock returned NULL by default.
Why did it fail to catch the invocation? There are several options:
CreateCommunicationInterface may be overloaded and your setup matched another overload that you did not expect
filters (It.IsAny..) didn't match the actual arguments
(..)
Klaus Gütter noted in the comments about the difference of Guid and Guid?. In fact, the filter you are using is It.IsAny() while in the test you pass:
Guid? g = new Guid();
g is not an object of type Guid, it's Nullable<Guid>, hence the filter looking for any-Guid did not match. The code compiled, because the result of the expression It.IsAny<Guid>() fits Guid? wanted by the method, but still the types don't match.
If you try It.IsAny<Guid?>() it will probably match fine and return what you wanted.
moq.Setup(m => m.CreateCommunicationInterface(It.IsAny<Guid?>(), It.IsAny<string>()))
.Returns((Guid? guid, string value) => GetProgrammerMoq(guid, value));

How to test if method returns expected data type?

Is it possible to create a NUnit Test method to check if the method returns the expected data type ?
Here's what I mean:
I've a static string that takes two parameters and checks to see if it matches with another string. If it does the methods simply returns that string.
I want to test to ensure that this method does infact return type of string and any exceptions that might occur.
Sample Code:
public static string GetXmlAttributeValue(this XmlElement element, string attributeName)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
if (attributeName == null)
{
throw new ArgumentNullException("attributeName");
}
string attributeValue = string.Empty;
if (element.HasAttribute(attributeName))
attributeValue = element.Attributes[attributeName].Value;
else
throw new XmlException(element.LocalName + " does not have an attribute called " + attributeName);
return attributeValue;
}
Here's how my solution is looking:
I'd like to write my test code within the TestLibrary class library.
Normally, there is no need to test the return type. C# is statically typed language, so this method cannot return something else different than string.
But If you want to write a test, which will fail if someone changes the return type, you can do something like this:
Assert.That(result, Is.TypeOf<string>());
To test for the return type you can use the Is.TypeOf<yourType> syntax mentioned by #dimitar-tsonev. Here is a list of the supported type contraints:
You also mention that you want to write tests to verify the exceptions. For that you can either use the ExpectedExceptionAttribute attribute as documented here or the exception asserts syntax as documented here.
You Don't Need To Test For the method to return a certain data type because it can only return the specific return type. You could run the method and use an Assert to check it isn't null, then you know the method has returned the correct type.
var result = GetXmlAttributeValue(par1,par2);
Assert.isNotNull(result);
Hope This helps!

Visual Studio Team Test: How to unit test "?" operator with only Asserts() and not using any tool

I need to write some unit test cases to test my code in C# Visual Studio Team Test framework.
Below is the method I want to test:
public static ObjectID CreateObjectID(ObjectID xrmObjectID)
{
return new ObjectID
{
Id = xrmAssociation.ID != null ? xrmAssociation.ID.Id : Guid.Empty;
};
}
In the above method, I need to write unit test cases to cover the conditional statements, for example:
Id = xrmAssociation.ID != null ? xrmAssociation.ID.Id : Guid.Empty;
So I wrote the following unit test method:
namespace WebApi.Test
{
[TestClass]
public class ApiTest
{
[TestMethod]
[ExpectedException(typeof(NullReferenceException), "A userId of null was inappropriately allowed.")]
public void CreateObjectIDShouldCheckConditionalBranch()
{
Xrm.objectID Input = new Xrm.objectID();
Input = null;
WebApiRole.Api.CreateObjectID(Input);
var expected = default(WebApi.ObjectID);
Assert.IsTrue(expected == WebApi.CreateObjectID(Input), "Failed");
}
}
}
This test passed, but it is actually not testing what I intend to test i.e. It should assign "Guid.Empty" when "null" is being passed. It just throws the exceptions of NullReference and thus the test passes.
I'd suggest writing one test for each separate case. That way, you can more easily tweak the testing code should requirements change.
I'd proceed like this (and I'll also take a guess and assume you're modelling Dynamics CRM, judging by the data)
[TestMethod]
public void AssociationCreationFromXrmShouldDefaultWhenAssociationHoldingIsNull()
{
Xrm.pv_association input = new Xrmpv_association();
input.pv_AssociationHolding = null;
var output = PVWebApiRole.ApiModelFactory.CreateAssociationFromXrm(Input);
// The fact that 'output' is valid should be tested separately
Assert.AreEqual(output.AssociationHoldingId, Guid.Empty);
}
[TestMethod]
public void AssociationCreationFromXrmShouldKeepNotNullAssociationHolding()
{
var sampleReference = new EntityReference("yourlogicalName", Guid.Parse("00000000-0000-0000-0000-000000000000"));
Xrm.pv_association input = new Xrmpv_association();
input.pv_AssociationHolding = sampleReference;
var output = PVWebApiRole.ApiModelFactory.CreateAssociationFromXrm(Input);
// The fact that 'output' is valid should be tested separately
Assert.AreEqual(output.AssociationHoldingId, sampleReference.Id);
}
and so on and so forth, two tests for each field, one to test the true side of the conditional and one for the false side (a couple of generic methods, one for OptionSet fields and one for EntityReference fields could be built and called several times, making the code short and fast to write).
Also, I think you should tweak CreateAssociationFromXrm to make it throw an ArgumentException if input is null (a couple tests of specifically that are of course to be written beforehand).
Using the ExpectedException annotation can be risky particularly when checking for a generic exception like NullReferenceException that could be thrown in other circumstances.
It seems like what you want to do is check that a specific property is not null in which case you would be much better off using the IsNotNull() assertion e.g.
var actual = PVWebApiRole.ApiModelFactory.CreateAssociationFromXrm(Input);
Assert.IsNotNull(actual.CreatedByUserProfileId);
For general help on debugging your NullReferenceException see What is a NullReferenceException and how do I fix it?
As I already pointed out in my comments your problem is that your CreateAssociationFromXrm() method assumes the xrmAssociation parameter is non-null when it does checks like the following:
xrmAssociation.pv_CreatedByUserProfileID != null ? xrmAssociation.pv_CreatedByUserProfileID.Id : Guid.Empty
You can avoid this by adding null checks to specific conditional statements e.g.
xrmAssociation != null && xrmAssociation.pv_CreatedByUserProfileID != null ? xrmAssociation.pv_CreatedByUserProfileID.Id : Guid.Empty
Stylistic suggestion
Often it is better to disallow null inputs completely so you may actually want to check for null at the start of your method and throw an ArgumentNullException e.g.
public static Association CreateAssociationFromXrm(Xrm.pv_association xrmAssociation)
{
if (xrmAssociation == null) throw new ArgumentNullException("xrmAssociation", "xrmAssociation cannot be null");
// Rest of your existing logic goes here
}

Verifying a call parameter via a callback in NSubstitute

I have a failing test in NSubstitute because a parameter passed in to a substituted call does not match. Here is the relevant code that is being tested:
// Arrange
PermissionsProviderSub = Substitute.For<IPermissionsProvider>();
MenuDataProviderSub = Substitute.For<IMenuDataProvider>();
PermissionsProviderSub.GetPermissions(UserId).Returns(ExpectedUserPermissions);
MenuDataProviderSub.GetMenuData(ExpectedUserPermissions.AuthorisedPageIds).Returns(Arg.Any<IList<BusinessFocusArea>>());
var sut = new MenuViewModelFactory(MenuDataProviderSub, PermissionsProviderSub);
// Act
var result = sut.Create();
// Assert
MenuDataProviderSub.Received().GetMenuData(ExpectedUserPermissions.AuthorisedPageIds);
The problem occurs in the ExpectedUserPermissions.AuthorisedPageIds property, which looks like this:
public IEnumerable<string> AuthorisedPageIds
{
get
{
return ApplicationPagePermissions != null ?
ApplicationPagePermissions.Select(permissionSet => permissionSet.PageId) :
Enumerable.Empty<string>();
}
}
As you can see, there is a LINQ Select, which is extracting the PageId property from within the ApplicationPagePermissions collection and returning it as an IEnumerable<string>. Because the projection within that property creates a new object, the substitution does not match, as it sees the 2 objects as being different.
Can I create a callback on the parameter passed in to GetMenuData so that I can examine the value of it?
The documentation on NSubstitute callbacks only talks about examining the return value from a call, rather than a parameter passed into the call.
Typical. As soon as I post to SO, the answer presents itself. Rather than expecting a specific object when creating the substitute call, I expect any instance of type IEnumerable<string> and create a callback when checking the Received() call that actually verifies the values. The substitute call becomes this:
MenuDataProviderSub.GetMenuData(Arg.Any<IEnumerable<string>>()).Returns(Arg.Any<IList<BusinessFocusArea>>());
The Received() check becomes this:
MenuDataProviderSub.Received().GetMenuData(Arg.Is<IEnumerable<string>>(a => VerifyPageIds(ExpectedUserPermissions.AuthorisedPageIds, a)));
private static bool VerifyPageIds(IEnumerable<string> expected, IEnumerable<string> actual)
{
var expectedIds = expected.ToList();
var actualIds = actual.ToList();
return expectedIds.Count == actualIds.Count && expectedIds.All(actualIds.Contains);
}

How To write a generic class/method in C# 2.0 to return a List of objects or just a simple string based on a condition?

I have a webservice which has a method that returns a List of Payment objects provided with some input parameters. However if the input parameters are not in the correct format, I would like to return an error message which is of type string, not a List of Payment objects. I would like do this using Generic Classes concept in C#. Anyone has any idea about how I can manage to do this ?
Many thanks,
Here is some code:
[WebMethod]
public List<Payment> GetPayments(string firstDate, string lastDate, string entegrationStatus)
{
if (Common.IsDateTime(firstDate) && Common.IsDateTime(firstDate) && Common.IsValidEntegrationStatus(entegrationStatus))
{
return paymentManager.GetPayments(firstDate, lastDate, entegrationStatus);
}
else
{
return "ERROR MESSAGE";
}
}
I'm fairly sure all you need to do is throw an exception in your service method. This will populate the Error property of the async event args that are returned back to the client. The client can check for errors in its 'async completed' event handler using this property and handle it accordingly.
This is probably a better design than just sending back a string as well because it separates a regular return message from an error return message.
It's as simple as:
Edit - Using the code you posted:
[WebMethod]
public List<Payment> GetPayments(string firstDate, string lastDate, string entegrationStatus)
{
if (Common.IsDateTime(firstDate) && Common.IsDateTime(firstDate) && Common.IsValidEntegrationStatus(entegrationStatus))
{
return paymentManager.GetPayments(firstDate, lastDate, entegrationStatus);
}
else
{
throw new ArgumentException("Your error message.");
}
}
If you REALLY want to do it, you can use a Tuple-like class (they introduced Tuples in C# 4.0). If you are using C# 2.0 then you can use KeyValuePair<List<YourObject>, string>. Be aware that I'm NOT suggesting you do it! You should throw an exception, or put the string message as an out parameter.
well you could do something simply like having an ErrorString property on your object, and if your main method fails, set the ErrorString and return null from your method
SomeObject o = new SomeOject();
ILIst<Things> things = o.GetThings();
if(things == null)
Response.Write(o.ErrorString)
A generic isn't really suitable for this use, because you cannot return a generic type based on a runtime condition within a generic method (since the method must be compiled with an exact type to run in the first place).
A common approach is to use an out parameter for your list and your string, and have your method return a bool denoting whether the list was returned. These methods are usually prefixed with Try.... eg
bool TryGetList<T>(out IList<T> lst, out string Error) {
if (!somcondition) {
Error = "err!";
return false;
}
lst = ...
return true;
}
The other technique is simply to use exceptions, but they can be more costly if you are likely to have errors frequently. An ArgumentException for example will let you specify which argument was invalid, and the caller can check the ParamName of the caught exception to decide what he should do afterwards.

Categories

Resources