For ASP.NET Boilerplate, I am trying to implement Xunit test for the project. Is there any method to provide the parameters to test methods and configure the test methods process order.
In the normal test project, I could use [InlineData("Test", 3)] to provide the value to test methods public async void AllInOne_Test(string userName, int count), but for ASP.NET Boilerplate, it did not pass the value to test method.
I also want to process TestB after TestB, how could I achieve this?
Update1:
For InlineData issue, I could inherit TheoryAttribute like below:
public sealed class MultiTenantTheoryAttribute : TheoryAttribute
{
public MultiTenantTheoryAttribute()
{
if (!CloudConsts.MultiTenancyEnabled)
{
Skip = "MultiTenancy is disabled.";
}
}
}
And then, use it like below:
[MultiTenantTheory]
[InlineData("Test_CreateCoupon")]
public async Task CreateCoupon_Test(string title)
{
//....
}
But, I still have an issue with test method processing order.
[MultiTenantTheory]
[InlineData("Test_CreateCoupon")]
public async Task CreateCoupon_Test(string title)
{
//...
}
[MultiTenantTheory]
[InlineData("Test_CreateCoupon", "Test_UpdateCoupon")]
public async Task UpdateCoupon_Test(string oldTitle, string updateTitle)
{
//。。。
}
In my tests, I have CreateCoupon_Test and UpdateCoupon_Test, I want to exec CreateCoupon_Test, then UpdateCoupon_Test when I run all tests. But, currently, its order is random, and I got UpdateCoupon_Test run before CreateCoupon_Test, then my tests failed, since I update the record which has not been created.
Related
Suppose I have a custom Gradle task that uses ExecOperations.javaexec() in its code:
public class MyTask extends DefaultTask {
private final ExecOperations execOps
#Inject
public MyTask(ExecOperations execOps) {
this.execOps = execOps;
}
#TaskAction
public void run() {
ExecResult result = execOps.javaexec(spec -> {
// classpath is set to some jar with a main class
spec.classpath(...);
spec.args(...);
});
// Do more stuff with result
}
}
The issue I have is that I am not sure how I can create a Spock test fixture for it to validate that the jar is being run with the correct arguments without actually running the jar itself. (The jar makes remote calls, for example, which I want to avoid).
It seems like the only plausible way forward is to potentially find a way to expose the ExecOperations for testing and possibly replace it with a stub, along with turning the Action<JavaExecSpec> from a mere lambda to something more substantial. Any ideas would be appreciated.
I've come across an interesting error. I have two test files for my xamarin mobile application, both testing view models:
public class TestFirstViewModel : MvxIoCSupportingTest
{
public void AdditionalSetup() {
//Register services and dependencies here.
}
[Fact]
public TestMethod1() {
// Successful test code here.
}
}
That's in one file. In another file, I have:
public class TestSecondViewModel : MvxIoCSupportingTest
{
public void AdditionalSetup() {
//Register services and dependencies here, slightly different from first
}
[Fact]
public TestMethod2() {
// Successful test code here.
}
}
When I run these files individually (I'm using xunit), they work just fine. However, when I run them together, I get the following error on one of the test cases:
Result Message: Cirrious.CrossCore.Exceptions.MvxException : You cannot create more than one instance of MvxSingleton
Result StackTrace:
at Cirrious.CrossCore.Core.MvxSingleton`1..ctor()
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer..ctor(IMvxIocOptions options)
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.Initialize(IMvxIocOptions options)
at Cirrious.MvvmCross.Test.Core.MvxIoCSupportingTest.ClearAll()
at Cirrious.MvvmCross.Test.Core.MvxIoCSupportingTest.Setup()
at Project.Test.TestFirstViewModel.TestMethod1() in ...
Can anyone tell me what's going on here?
The issue stems from the parallelization of XUnit without the option to do proper tear-down. You could diable parallelization in the AssemblyIndo.cs file in you test project by adding:
[assembly: CollectionBehavior(DisableTestParallelization = true)]
I ended up solving this question by changing testing frameworks. I had different ioc singleton initializations, because, well, they're different test cases and needed different inputs/mocks. Instead of using Xunit, I resorted to Nunit where their cache clearing was much more defined: Xunit doesn't exactly believe in setup and tear-down, so it made a test environment like this more difficult.
I fixed the issue by using the collection attribute.
[Collection("ViewModels")]
class ViewModelATest : BaseViewModelTest {
...
}
[Collection("ViewModels")]
class ViewModelBTest : BaseViewModelTest {
...
}
The base view model test class has the mock dispatcher and performs the singleton registrations in the additional setup method.
Each of my tests calls ClearAll() at the beginning.
I hade some success with setup things in a constructor and add this check:
public PaymentRepositoryTests()
{
if (MvxSingletonCache.Instance == null)
{
Setup();
}
//other registerings.
}`
Also I did implement the IDisposable Interface
public void Dispose()
{
ClearAll();
}
But tbh not sure how much impact that had..
It works ok with xunit
Copy MvxIocSupportingTest and Mvxtest in your xunit PCL project.
Modify MvxTest to remove the attributes and use a simple contructor:
public class MvxTest : MvxIoCSupportingTest
{
protected MockMvxViewDispatcher MockDispatcher { get; private set; }
public MvxTest()
{
Setup();
}
...
And in each of you test, derive from IClassFixture
public class TestRadiosApi : IClassFixture<MvxTest>
{
[Fact]
public async Task TestToken()
{
...
xunit will create the MvxTest class only once for all tests.
I'm getting into writing unit testing and have implemented a nice repository pattern/moq to allow me to test my functions without using "real" data. So far so good.. However..
In my repository interface for "Posts" IPostRepository I have a function:
Post getPostByID(int id);
I want to be able to test this from my Test class but cannot work out how.
So far I am using this pattern for my tests:
[SetUp]
public void Setup()
{
mock = new Mock<IPostRepository>();
}
[Test]
public void someTest()
{
populate(10); //This populates the mock with 10 fake entries
//do test here
}
In my function "someTest" I want to be able to call/test the function GetPostById. I can find the function with mock.object.getpostbyid but the "object" is null.
Any help would be appreciated :)
iPostRepository:
public interface IPostRepository
{
IQueryable<Post> Posts {get;}
void SavePost(Post post);
Post getPostByID(int id);
}
I'm not sure what unit testing framework you are using, but I am using NUnit. I'm not a unit testing pro, but I know enough to get me started and to get results.
I normally have a service layer, and this will call my post repository:
public class PostService
{
private readonly IPostRepository postRepository;
public PostService(IPostRepository postRepository)
{
if (postRepository== null)
{
throw new ArgumentNullException("postRepository cannot be null.", "postRepository");
}
this.postRepository = postRepository;
}
public Post GetPostById(int id)
{
return postRepository.GetPostById(id);
}
}
Your unit tests could look like this:
[TestFixture]
public class PostServiceTests
{
private PostService sut;
private Mock<IPostRepository> postRepositoryMock;
private Post post;
[SetUp]
public void Setup()
{
postRepositoryMock = new Mock<IPostRepository>();
sut = new PostService(postRepositoryMock.Object);
post = new Post
{
Id = 5
};
}
[Test]
public void GetPostById_should_call_repository_to_get_a_post_by_id()
{
int id = 5;
postRepositoryMock
.Setup(x => x.GetPostById(id))
.Returns(post).Verifiable();
// Act
Post result = sut.GetPostById(id);
// Assert
Assert.AreEqual(post, result);
postRepositoryMock.Verify();
}
}
I hope this helps.
If you want your mock object to return a result (not null), you need to set it up:
mock.Setup( m => m.GetPostByID( 5 ) ).Returns( new Post() );
What you return exactly is up to you of course.
Update:
If you need to use the method parameters you can also setup a CallBack. For example:
mock.Setup( m => m.GetPostByID( It.IsAny<int>() ) )
.Callback( id => return new Post{ Id = id; } );
This may make your setup code much easier since you don't need to prime the mock with data.
If you want to test the real implementation of GetPostById, do so via the real implementation of IPostRepository. Moq (and mocks in general) are only for situation where you don't want to use the real thing.
In other words prime your database with some posts, new up the real repository, call GetPostById and make assertions on the result. This is not strictly a unit test though, but an integration test because it includes the database.
I have 3 test cases i.e. 1 2 3. How will i give priority as 2 1 3 while executing maven command.
I assume you want to do it because you need some prerequisition prior the test can be run. You can do it by #Before Annotation prior the actual testcase, or you can call other tests from the test method.
Say, testClient() test will test and verify that new client can be added to the system. Then you can do this:
#Test
public void testWithdrawal(){
testClient(); // i need client existing before the test can be run
// ... do something else
}
In that case you have assured that prerequisites are fullfilled and dont have to worry much about the testcases order
EDIT
I think I understand your needs, because I am in quite similar situation. How I solved it:
For create I have special class, which can create me a data and return needed data. So, i have something like:
#Test
public void testShare(){
CreateTests create = new CreateTests; //This will just initialize the object
create.testCreate(); // this method can contain steps needed to create
String justCreatedEntity = create.getEntity(); // just example how you can use the just created entity in further tests
}
And my class to solve the create is something like this
public class CreateTests{
private static String entity; //static because i dont want it to be flushed when test ends
public void testCreate() throws Exception{
WebDriverBackedSelenium selenium = new WebDriverBackedSelenium(driver, "baseURL");
selenium.... // All the selenium stuff
setEntity(selenium.getText("id=mainForm.createdentity"));
}
public void setEntity(String ent){
this.entity = ent;
}
public String getEntity(){
return entity;
}
Its just an outline - but basically, I have these "crucial" entities as standalone objects, called by the test class. Inside test, i verify everything throgh getters. Like:
Assert.assertNotNull(create.getAuctionID(),"New Entity is NULL!" );
You can run mvn test with options to specify a single test, or multiple tests. The order they are run in is the order specified on the command line.
Reference is here: http://maven.apache.org/plugins/maven-surefire-plugin/examples/single-test.html
Note that Java suggests that the good unit testing practice of tests not requiring to be run in order and test to not rely on each other:
http://java.sun.com/developer/Books/javaprogramming/ant/ant_chap04.pdf
Given this test fixture:
[TestClass]
public class MSTestThreads
{
[TestMethod]
public void Test1()
{
Trace.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
[TestMethod]
public void Test2()
{
Trace.WriteLine(Thread.CurrentThread.ManagedThreadId);
}
}
Running the test with MSTest through Visual Studio or command line prints two different thread numbers (yet they are run sequentially anyway).
Is there a way to force MSTest to run them using a single thread?
I solved this problem with locking:
public static class IntegrationTestsSynchronization
{
public static readonly object LockObject = new object();
}
[TestClass]
public class ATestCaseClass
{
[TestInitialize]
public void TestInitialize()
{
Monitor.Enter(IntegrationTestsSynchronization.LockObject);
}
[TestCleanup]
public void TestCleanup()
{
Monitor.Exit(IntegrationTestsSynchronization.LockObject);
}
//test methods
}
// possibly other test cases
This can of course be extracted to a base test class and reused.
I've fought for endless hours to make MSTest run in a single threaded mode on a large project that made heavy use of nHibernate and it's not-thread-safe (not a problem, it's just not) ISession.
We ended up more time writing code to support the multi-threaded nature of MSTest because - to the best of my and my teams knowledge - it is not possible to run MSTest in a single threaded mode.
You can derive your test class from
public class LinearTest
{
private static readonly object SyncRoot = new object();
[TestInitialize]
public void Initialize()
{
Monitor.Enter(SyncRoot);
}
[TestCleanup]
public void Cleanup()
{
Monitor.Exit(SyncRoot);
}
}
We try hard to make out tests isolated from each other. Many of them achieve this by setting up the state of a database, then restoring it afterwards. Although mostly tests set up different data, with some 10,000 in a run there is a fair chance of a collision unless the code author of a test takes care to ensure its initial data is unique (ie doesn't use the same primary keys as another test doing something similar). This is, frankly, unmanageable, and we do get occasional test failures that pass second time around. I am fairly sure this is caused by collisions that would be avoided running tests strictly sequentially.
The way to make an MSTest method run in single-threaded mode:
Nuget:
install-package MSTest.TestAdapter
install-package MSTest.TestFramework
In your test source on those methods that need to run while no other tests are running:
[TestMethod]
[DoNotParallelize]
public void myTest(){
//
}
Whilst it is a cop out answer, I would actually encourage you to make your code thread-safe. The behaviour of MSTest is to ensure isolation as Richard has pointed out. By encountering problems with your unit tests you are proving that there could be some problems in the future.
You could ignore them, use NUnit, or deal with them and continue to use MSTest.
I tried a bit of a different approach, because the underlying problem is that the names of the pipes are the problem. So I made a fakePipe, derived it from the one I use in the program. And named the pipe with the tests name.
[TestClass]
public class PipeCommunicationContractTests {
private PipeDummy pipe;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext { get; set; }
[TestInitialize]
public void TestInitialize() {
pipe = new PipeDummy(TestContext.TestName);
pipe.Start();
}
[TestCleanup]
public void TestCleanup() {
{
pipe.Stop();
pipe = null;
}
...
[TestMethod]
public void CallXxOnPipeExpectResult(){
var result = pipe.Xx();
Assert.AreEqual("Result",result);
}
}
It appears to be a bit faster, since we can run on multiple cores and threads...