とりあえずASP.NET5 beta7をUbuntuで動かしてみる
UbuntuでASP.NET5 beta7が動いたのでメモ
参考にしたサイト
Ubuntu Desktop で ASP.NET 5 Beta7 を CoreCLR で動かす - きよくらの備忘録
Installing ASP.NET 5 On Linux — ASP.NET 0.0.1 documentation
環境は、Azure上のUbuntu Server 15.04
素の状態から始めます。
まあ上記サイトの手順ほぼそのままですが、monoは入れてません。
説明なし
つらつらとコマンドだけ並べておく
sudo apt-get install unzip
curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh
dnvm upgrade -r coreclr
sudo apt-get install libunwind8 gettext libssl-dev libcurl3-dev zlib1g
sudo apt-get install make automake libtool curl curl -sSL https://github.com/libuv/libuv/archive/v1.4.2.tar.gz | sudo tar zxfv - -C /usr/local/src cd /usr/local/src/libuv-1.4.2 sudo sh autogen.sh sudo ./configure sudo make sudo make install sudo ldconfig
動くかどうかサンプルで試します
git clone https://github.com/aspnet/Home.git
cd Home/samples/1.0.0-beta7/HelloMvc
dnu restore
起動します
dnx kestrel
Azureだとポートが空いてないので空けておきます
monoインストールしないでもとりあえず動きました。
それ以上はまだ触ってないのでなんともかんとも
Moqでprotectedメソッドをモックする
通常は、テストしたいクラスが利用しているクラスのpublicメソッドをモックしますが
たまに自クラスのprotectedメソッドをモックしたい時があります。
(そりゃ設計が悪いって話もあるでしょうが、ここでは置いておきましょう)
こんなクラスがあります。
public class Hoge { public bool Foo() { return Bar(); } protected virtual bool Bar() { return true; } }
Barメソッドをモックしてみます
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Moq.Protected; namespace MoqSample { [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { var mock = new Mock<Hoge>(); mock.Protected().Setup<bool>("Bar").Returns(false); Assert.IsFalse(mock.Object.Foo()); } } }
Moq.Protectedをusingしてください。
あとは、まあ見たままですかね
Setupメソッドの型引数なしバージョンだとReturnsが無いので注意
Knockout.jsの初期値をDOMから取得する
Knockout.jsを使うときにたまに困るのがDOMの値を初期値にしたい時です。
なんか地道にJQueryでデータを取得してプロパティに代入してたのですが
ちょっと調べてみたらカスタマイズしてDOMからデータを取得することができました。
いろいろやり方はあるのでしょうが、私はこんな感じで実装してみました。
ko.bindingHandlers.valueWithInit = { init: function (element, valueAccessor, allBindingsAccessor, data, context) { var property = valueAccessor(), value = element.value; property(value); ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, data, context); }, update: ko.bindingHandlers.value.update }; ko.bindingHandlers.textWithInit = { init: function (element, valueAccessor, allBindingsAccessor, data, context) { var property = valueAccessor(), text = $(element).text(); property(text); ko.bindingHandlers.text.init(element, valueAccessor, allBindingsAccessor, data, context); }, update: ko.bindingHandlers.text.update }; ko.bindingHandlers.checkedWithInit = { init: function (element, valueAccessor, allBindingsAccessor, data, context) { var property = valueAccessor(), checked = element.checked; property(checked); ko.bindingHandlers.checked.init(element, valueAccessor, allBindingsAccessor, data, context); }, update: ko.bindingHandlers.checked.update };
これをvalueとかtextバインディングみたいに
<input name="FirstName" type="text" data-bind="valueWithInit: firstName">
こんな感じでかけます。
これですっきり
ChainingAssertionでテストをエレガントに
いつもの通りひさしぶりのブログです。
以前から使っている@neuecc先生作のChainingAssertionについて書きます。
基本的な使い方は、こんな感じ
var actual = Add(5,3); actual.Is(8);
MSTestだと
Assert.AreEqual(8, actual);
う~ん
MSTestがイケてないところの1つに例外のテストがあります。
[TestMethod] [ExpectedException(typeof(ArgumentException))] public void 例外が発生する() { // 例外が発生する処理 }
発生する例外を属性に設定してあげればOKです。
これはこれで良さそうな気もするのですが、
例外が発生した後に別なチェックもしたいとかができない!
これをChainingAssertionだと
[TestMethod] public void 例外が発生する() { AssertEx.Throws<ArgumentException>(() => Add(5, 3)); // 引き続きテスト }
これであればこの処理の後に引き続きテストが続けられます。
例外メッセージを確認したい場合は、戻り値がExceptionになっているので
AssertEx.Throws<ArgumentException>(() => Add(5, 3)).Message.Is("正の数を指定してください");
てな感じで可能になります。
こうゆう設計は見習いたいなー
ということ皆さんChainingAssertion使いましょう
AutoMapperでUpperCamelCaseとPascalCaseをMapする
今年、初ブログだったりします。(気力がね・・・)
さてタイトルの通りAutoMapperでUpperCamelCaseとPascalCaseをMapしたい。
C#でUpperCamelCaseを使うことはほぼ無いのですが
DBがOracleだったりしてORMもシンプルなものだったりすると
UpperCamelCaseで定義したクラスに一旦受けざる負えない時もあります。
それを簡単にPascalCaseで定義したクラスに移したいって時の話です。
(まああまり需要は無いですかねー)
以前に@xin9leさんが、このような記事を書かれています。
AutoMapperで特定の命名規則で変換する - xin9le.net
基本的にはこれでできたのですが、これにプラスして
PascalCaseからUpperCamelCaseへのMapもしたいのです。
これがかなり嵌りました。
とりあえずググると
Automapper: How to leverage a custom INamingConvention? - Stack Overflow
こんな感じで出てきますが、CreateProfileしてWithProfileするやり方だとどうもうまく行きませんでした。
で、ようやくできたのがこのやり方
とりあえず適当に受け渡しするクラスを作ります。
class Employee { public int EmployeeId { get; set; } public string EmployeeName { get; set; } } class EmployeeDataModel { public int EMPLOYEE_ID { get; set; } public string EMPLOYEE_NAME { get; set; } }
INamingConventionを実装するクラスを作ります。
public class UpperSnakeCaseNamingConvention : INamingConvention { public string SeparatorCharacter { get { return "_"; } } public Regex SplittingExpression { get { return new Regex(@"[\p{Lu}0-9]+(?=_?)"); } } }
Profileクラスを継承するクラスをUpperCamelCaseからPascalCaseに変換するクラスと
逆にPascalCaseからUpperCamelCaseに変換するクラスを作ります。
class UpperSnakeToPascalProfile : Profile { public override string ProfileName { get { return "UpperScakeToPascal"; } } protected override void Configure() { // こちらはSourceに対して上で作ったINamingConventionを実装したクラスを設定 this.SourceMemberNamingConvention = new UpperSnakeCaseNamingConvention(); // 上の設定でMapしたいクラスは、ここでCreateMapすること this.CreateMap<EmployeeDataModel, Employee>(); } } class PascalToUpperSnakeProfile : Profile { public override string ProfileName { get { return "PascalToUpperSnake"; } } protected override void Configure() { // こちらはDestinationに対して上で作ったINamingConventionを実装したクラスを設定 this.DestinationMemberNamingConvention = new UpperSnakeCaseNamingConvention(); this.CreateMap<Employee, EmployeeDataModel>(); } }
で、これを呼び出してうまく行くかテストします。
[TestClass] public class UnitTest1 { public UnitTest1() { // Mappingの設定をする Mapper.Initialize(config => { // AddProfileで上で作成したProfileクラスを設定 config.AddProfile<UpperSnakeToPascalProfile>(); config.AddProfile<PascalToUpperSnakeProfile>(); }); Mapper.AssertConfigurationIsValid(); } [TestMethod] public void TestMethod1() { var dm = new EmployeeDataModel { EMPLOYEE_ID = 1, EMPLOYEE_NAME = "山田太郎" }; var dto = Mapper.Map<Employee>(dm); Assert.AreEqual(dm.EMPLOYEE_ID, dto.EmployeeId); Assert.AreEqual(dm.EMPLOYEE_NAME, dto.EmployeeName); } [TestMethod] public void TestMethod2() { var dto = new Employee { EmployeeId = 2, EmployeeName = "佐藤一郎" }; var dm = Mapper.Map<EmployeeDataModel>(dto); Assert.AreEqual(dto.EmployeeId, dm.EMPLOYEE_ID); Assert.AreEqual(dto.EmployeeName, dm.EMPLOYEE_NAME); } }
という感じでちゃんとMapすることができました。
TFS2013にPullRequestがきました
ひさしぶりのブログになってしまいました。
TFS2013 Update4でPullRequest機能が実装されました。
もしかしたらアクセスレベルがPremium以上とかになるんじゃないかと思ったんですけど
大丈夫でした。
こんな感じでプル要求のタブができてます。
で、プル要求
あとはメンドイので割愛
これでレビューとかマージとか楽になりますねー