I am using TestCaseSource with NUnit. The below code generates IEnumerable of TestCaseData that represent an archive entry, which is an input for a test.
private class GithubRepositoryTestCasesFactory
{
private const string GithubRepositoryZip = "https://github.com/QualiSystems/tosca/archive/master.zip";
public static IEnumerable TestCases
{
get
{
using (var tempFile = new TempFile(Path.GetTempPath()))
using (var client = new WebClient())
{
client.DownloadFile(GithubRepositoryZip, tempFile.FilePath);
using (var zipToOpen = new FileStream(tempFile.FilePath, FileMode.Open))
using (var archive = new ZipArchive(zipToOpen, ZipArchiveMode.Read))
{
foreach (var archiveEntry in archive.Entries.Where(a =>
Path.GetExtension(a.Name).EqualsAny(".yaml", ".yml")))
{
yield return new TestCaseData(archiveEntry);
}
}
}
}
}
}
[Test, TestCaseSource(typeof (GithubRepositoryTestCasesFactory), "TestCases")]
public void Validate_Tosca_Files_In_Github_Repository_Of_Quali(ZipArchiveEntry zipArchiveEntry)
{
var toscaNetAnalyzer = new ToscaNetAnalyzer();
toscaNetAnalyzer.Analyze(new StreamReader(zipArchiveEntry.Open()));
}
The above code fails on the following line:
zipArchiveEntry.Open()
with an exception:
System.ObjectDisposedException "Cannot access a disposed object.
Object name: 'ZipArchive'."
Is there any way to control the disposing of objects created for test data case?
The problem is that the ZipArchive and its children are being disposed of at the end of the using block.
Try rigging up something like this within your fixture fixture:
// MyDisposable an IDisposable with child elements
private static MyDisposable _parent;
// This will be run once when the fixture is finished running
[OneTimeTearDown]
public void Teardown()
{
if (_parent != null)
{
_parent.Dispose();
_parent = null;
}
}
// This will be run once per test which uses it, prior to running the test
private static IEnumerable<TestCaseData> GetTestCases()
{
// Create your data without a 'using' statement and store in a static member
_parent = new MyDisposable(true);
return _parent.Children.Select(md => new TestCaseData(md));
}
// This method will be run once per test case in the return value of 'GetTestCases'
[TestCaseSource("GetTestCases")]
public void TestSafe(MyDisposable myDisposable)
{
Assert.IsFalse(myDisposable.HasChildren);
}
The key is to set the static member when creating the test case data, then disposing of it on the fixture tear down.
Related
I am using mock library in my .Net unit test and getting an error
cannot be accessed with an instance reference instead use type name.
I am getting this error at following line in my test method where it is calling cq.Instance. I am new to mock library. Could somebody let me know how do I call the static method?
attributeValue.Setup(cq => cq.Instance().CallQueryAsync(request, 1)).Returns(attrValue);
Actual method to be tested
public static async Task<AttributeValueList> GetAttributeSecDateValueList(int attrId)
{
try
{
var request = AttributeValue.ResolveRequest(attrId);
var response = await AsyncProxy<AttributeValue>.Instance().CallQueryAsync(request, (int)AttributeValue.OperationType.GetSecDateValues);
var coll = new AttributeValueList();
coll.AddRange(response);
return coll;
}
catch (Exception e)
{
throw e;
}
}
Proxy class
public class AsyncProxy<RT> : IDisposable
where RT : class, new()
{
readonly WebServiceProxy<RT> _wsProxy;
private AsyncProxy(WebServiceProxy<RT> webServiceProxy)
{
_wsProxy = webServiceProxy;
}
public static async Task<IEnumerable<RT>> Load(object parameters)
{
return await Instance().CallQueryAsync(parameters);
}
public static AsyncProxy<RT> Instance()
{
return new AsyncProxy<RT>(WebServiceProxy<RT>.Instance());
}
/// <summary>
/// Return result set of Poco as smartCollection
/// </summary>
public async Task<SmartCollection<RT>> CallQueryAsync(object request, int? uniqueIdentifier = null, bool isLongRunning = false, [CallerMemberName]string memberName = "")
{
//#if DEBUG
// var stopwatch = new Stopwatch();
// stopwatch.Start();
//#endif
try
{
// We want to get rid of the proxy as soon as we are done with it
using (_wsProxy)
{
var awaited = await _wsProxy.CallQueryAsync(request, uniqueIdentifier, isLongRunning);
if (awaited == null)
return null;
var observableCollection = new SmartCollection<RT>();
foreach (var item in awaited)
observableCollection.Add(item as RT);
return observableCollection;
}
}
finally
{
Dispose();
//#if DEBUG
// stopwatch.Stop();
// Debug.WriteLine(null);
// Debug.WriteLine($"****>>>>> AsyncProxy {memberName} took {stopwatch.ElapsedMilliseconds} ms <<<<<<<<****");
//#endif
}
}
}
test method
[TestMethod]
public void test()
{
Task<SmartCollection<AttributeValue>> attrValue = null;
var request = new AttributeValue();
var attributeValue = new Mock<AsyncProxy<AttributeValue>>();
attributeValue.Setup(cq => cq.Instance().CallQueryAsync(request, 1)).Returns(attrValue);
}
Currently i've got this code:
private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
{
foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
{
var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
if (declaredSymbol is IFieldSymbol fieldSymbol)
{
// SymbolFinder.FindReferencesAsync()
var b = fieldSymbol.Locations;
// context.SemanticModel.Compilation.
}
}
return false;
}
And this scenario:
private static readonly string TestSourceImplementsDisposableAndDoesMentionDisposableField = #"
using System;
using System.IO;
namespace ConsoleApplication1
{
public class SampleDisposable : IDisposable
{
public void Dispose()
{
}
}
public class SampleConsumer : IDisposable
{
private SampleDisposable _disposable = new SampleDisposable();
private IDisposable _ms = new MemoryStream();
public void Dispose()
{
_disposable?.Dispose();
_ms?.Dispose();
}
}
}";
Ultimately my desire is to figure out whether a dispose method is accessing a disposable field. Unfortunately i can't seem to find a way to get this working without using SymbolFinder, which requires a solution.
I did something similar with SymbolFinder and it was an easy thing to do - but how do i do it from the functionality available within a diagnostic?
Am i missing something obvious here?
You could simply use the SemanticModel to analyse the type used for the field like this:
private async Task<bool> IsMentionedInDisposeCallAsync(SyntaxNodeAnalysisContext context, FieldDeclarationSyntax fieldDeclarationSyntax)
{
foreach (var variableDeclaratorSyntax in fieldDeclarationSyntax.Declaration.Variables)
{
var declaredSymbol = context.SemanticModel.GetDeclaredSymbol(variableDeclaratorSyntax);
if (declaredSymbol is IFieldSymbol fieldSymbol)
{
var isDisposeable = CheckIsTypeIDisposeable(fieldSymbol.Type as INamedTypeSymbol);
// SymbolFinder.FindReferencesAsync()
var b = fieldSymbol.Locations;
// context.SemanticModel.Compilation.
}
}
return false;
}
private string fullQualifiedAssemblyNameOfIDisposeable = typeof(IDisposable).AssemblyQualifiedName;
private bool CheckIsTypeIDisposeable(INamedTypeSymbol type)
{
// Identify the IDisposable class. You can use any method to do this here
// A type.ToDisplayString() == "System.IDisposable" might do it for you
if(fullQualifiedAssemblyNameOfIDisposeable ==
type.ToDisplayString() + ", " + type.ContainingAssembly.ToDisplayString())
{
return true;
}
if(type.BaseType != null)
{
if (CheckIsTypeIDisposeable(type.BaseType))
{
return true;
}
}
foreach(var #interface in type.AllInterfaces)
{
if (CheckIsTypeIDisposeable(#interface))
{
return true;
}
}
return false;
}
Basically you would search through all interfaces of the class and the base class recursively to find the type corresponding to IDisposeable - which should be somewhere in the hierarchy.
I have the following class which is a TestFixture which has one test and a TestCaseSource that produces my TestCases. My test case actually contain both the actual result and the expected result which is wrapped in an Object called TestCaseEntity
namespace SomeNamespace
{
[TestFixture]
public class MyTest
{
static Client client;
static List<string> userIds = new List<string>();
[TestFixtureSetUp]
public void Init()
{
// Set up a client
client = new Client("server address"); // a HTTP client
// populate a List of userIds from a local text test file
userIds.Add(GetAllIdsFromTxtFile());
}
[Test, TestCaseSource(typeof(MyTestCaseEntityFactory), "MyTestCases")]
public void CheckExpectations(TestCaseEntity testCaseEntity)
{
if (!testCaseEntity.IsIdentical)
{
Log.Error("Log some shit");
Assert.Fail("fail assertions");
}
}
public class MyTestCaseEntityFactory
{
public static IEnumerable<TestCaseEntity> MyTestCases
{
get
{
foreach (string id in userIds)
{
// use the client and get the results, construct the new TestCaseEntity(...) and return;
yield return new TestCaseEntity("actualValue", "expectedValue resulting from the server call");
}
}
}
}
}
}
When I run my Test, I get the following error which is unfortunately not very helpful!
System.NullReferenceException : Object reference not set to an instance of an object.
Any suggestions on what I might have done wrong?
You foreach over allSalesDEDealIds but you seem to have not included it in your code example. It might be that this is the NullRefExceptionin your code?
Since I have converted my WCF methods to Async, my unit tests have failed, and I can't figure out the correct syntax to get them to work.
Cllient proxy class
public interface IClientProxy
{
Task DoSomething(CredentialDataList credentialData, string store);
}
service class
public class CredentialSync : ICredentialSync
{
private ICredentialRepository _repository;
private IClientProxy _client;
public CredentialSync()
{
this._repository = new CredentialRepository();
this._client = new ClientProxy();
}
public CredentialSync(ICredentialRepository repository, IClientProxy client)
{
this._repository = repository;
this._client = client;
}
public async Task Synchronise(string payrollNumber)
{
try
{
if (string.IsNullOrEmpty(payrollNumber))
{
.... some code
}
else
{
CredentialDataList credentialData = new CredentialDataList();
List<CredentialData> credentialList = new List<CredentialData>();
// fetch the record from the database
List<GetCredentialData_Result> data = this._repository.GetCredentialData(payrollNumber);
var pinData = this._repository.GetCredentialPinData(payrollNumber);
// get the stores for this employee
var storeList = data.Where(a => a.StoreNumber != null)
.GroupBy(a => a.StoreNumber)
.Select(x => new Store { StoreNumber = x.Key.ToString() }).ToArray();
var credential = this.ExtractCredentialData(data, pinData, payrollNumber);
credentialList.Add(credential);
credentialData.CredentialList = credentialList;
foreach (var store in storeList)
{
//this line causes an Object reference not set to an instance of an object error
await _client.DoSomething(credentialData, store.StoreNumber);
}
}
}
catch (Exception ex)
{
throw new FaultException<Exception>(ex);
}
}
Test Class
/// </summary>
[TestClass]
public class SynchTest
{
private Mock<ICredentialRepository> _mockRepository;
private Mock<IClientProxy> _mockService;
[TestInitialize]
public void Setup()
{
... some setups for repository which work fine
}
[TestMethod]
public async Task SynchroniseData_WithOneEmployee_CallsReplicateService()
{
this._mockService = new Mock<IClientProxy>();
this._mockService.Setup(x=>x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>()));
// arrange
string payrollNumber = "1";
CredentialSync service = new CredentialSync(this._mockRepository.Object, this._mockService.Object);
// act
await service.Synchronise(payrollNumber);
// assert
this._mockService.VerifyAll();
}
The error is when ClientProxy.DoSomething is called:
Object reference not set to an instance of an object
The parameters are both fine.
If I convert my ClientProxy.DoSomething method to a synchronous method
(public void DoSomething(...) )the code works fine, but I do need this to be called asynchronously
DoSomething returns null instead of returning a Task, and so you get an exception when awaiting it. You need to specify when building the mock that it should return a Task.
In this case it seems that you can simply return an already completed task using Task.FromResult so the mock setup should look like this:
this._mockService.Setup(...).Returns(Task.FromResult(false));
Beginning with the next version of .Net (4.6) you can use Task.CompletedTask like this:
this._mockService.Setup(...).Returns(Task.CompletedTask);
You can reduce the amount of clutter in the code by using ReturnsAsync
this._mockService.Setup(...).ReturnsAsync(false);
This way you can remove the Task.FromResult part of the code
I think you need to return the Task from the DoSomething mock
this._mockService.Setup(x => x.DoSomething(It.IsAny<CredentialDataList>(), It.IsAny<string>()))
.Returns(Task.FromResult<int>(0));
I have a static class wherein I am reading an XML to build a dictionary.
Now this initialization is done in the static constructor.
In order to test this Initialize method, I have to somehow stub out the reading of XML logic and just give it an XDocument for testing, but not sure how can I do that.
internal static class MasterMnemonicsLookup
{
private static Dictionary<string, StateCoverageMnemonic[]> masterMnemonics = new Dictionary<string, StateCoverageMnemonic[]>();
private static StateCoverageMnemonic[] stateCoverageMnemonics;
static MasterMnemonicsLookup()
{
Initialize();
}
private static void Initialize()
{
var resource = XDocument.Parse(GetResourceTextFile("MasterMnemonics.xml"));
var serializer = new XmlSerializer(typeof (MasterMnemonicsType));
var model = (MasterMnemonicsType) serializer.Deserialize(resource.CreateReader());
var stateCoverageMnemonicsList = new List<StateCoverageMnemonic>();
foreach (var masterMnemonic in model.MasterMnemonics)
{
var stateCoverageMnemonicsXml = new List<StateCoverageMnemonic>();
var excludedStates = RiskStates.None;
StateCoverageMnemonic allStateCoverageMnemonic = null;
foreach (var stateCoverageMnemonic in masterMnemonic.StateCoverageMnemonics)
{
var state = stateCoverageMnemonic.StateCode;
if (!state.HasFlag(RiskStates.All))
{
excludedStates = excludedStates | state;
var mnemonic = stateCoverageMnemonic.Mnemonic;
var coverageCode = stateCoverageMnemonic.CoverageCode;
var stateCoverageMnemonicTemp = new StateCoverageMnemonic(state, mnemonic, coverageCode);
stateCoverageMnemonicsXml.Add(stateCoverageMnemonicTemp);
}
else
{
//// TODO: If All occurs twice should we throw an exception
allStateCoverageMnemonic = new StateCoverageMnemonic(state, stateCoverageMnemonic.Mnemonic, stateCoverageMnemonic.CoverageCode);
}
}
if (allStateCoverageMnemonic != null)
{
stateCoverageMnemonicsXml.Add(new StateCoverageMnemonic(RiskStates.All ^ excludedStates, allStateCoverageMnemonic.Mnemonic, allStateCoverageMnemonic.CoverageCode));
}
stateCoverageMnemonicsList.AddRange(stateCoverageMnemonicsXml);
masterMnemonics.Add(masterMnemonic.MasterMnemonic, stateCoverageMnemonicsXml.ToArray());
}
stateCoverageMnemonics = stateCoverageMnemonicsList.ToArray();
}
private static string GetResourceTextFile(string filename)
{
string result = string.Empty;
using (Stream stream = typeof(MasterMnemonicsLookup).Assembly.GetManifestResourceStream("Geico.Applications.Business.CoverageApi.DomainLayer.DataLayer." + filename))
{
var streamReader = new StreamReader(stream);
result = streamReader.ReadToEnd();
}
return result;
}
}
Using static contructors in this way is not advised, and your scenario is a good example why. You might try the singleton pattern using a public instance constructor that accepts an XDocument. (You can use internal, but this makes it harder to unit test). This is a simple form of dependency injection.
For testing, an instance of your class can simply be created by your testing framework with the test XDocument.
For your live application, a static instance of your class can be initialized and held by a container type, and the appropriate XDocument can be passed in privately (within the container).
I agree with Darious Vaughan-Scott
But if you want to keep using the static constructor you may want to put the loading logic into a seperate class which makes it easier to test.
For example
internal class MasterMnemonicsLoader
{
public void Load(
XDocument resource,
Dictionary<string, StateCoverageMnemonic[]> masterMnemonics,
StateCoverageMnemonic[] stateCoverageMnemonics)
{
//Do the loading here
}
}
and in the Initialize method you can call the Load method
private static void Initialize()
{
var resource = XDocument.Parse(GetResourceTextFile("MasterMnemonics.xml"));
var loader = MasterMnemonicsLoader();
loader.Load(resource, masterMnemonics, stateCoverageMnemonics);